package http import ( "database/sql" "net/http" "net/http/httptest" "strings" "testing" "github.com/example/storage-appliance/internal/service/mock" ) func TestPoolsHandler(t *testing.T) { m := &mock.MockZFSService{} app := &App{DB: &sql.DB{}, ZFSSvc: m} req := httptest.NewRequest(http.MethodGet, "/api/pools", nil) w := httptest.NewRecorder() app.PoolsHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } body := w.Body.String() if body == "" { t.Fatalf("expected non-empty body") } } func TestCreatePoolHandler(t *testing.T) { m := &mock.MockZFSService{} j := &mock.MockJobRunner{} app := &App{DB: &sql.DB{}, ZFSSvc: m, JobRunner: j} body := `{"name":"tank","vdevs":["/dev/sda"]}` req := httptest.NewRequest(http.MethodPost, "/api/pools", strings.NewReader(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("X-Auth-User", "admin") req.Header.Set("X-Auth-Role", "admin") w := httptest.NewRecorder() app.CreatePoolHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } if !strings.Contains(w.Body.String(), "job_id") { t.Fatalf("expected job_id in response") } } func TestSharesNFSHandler(t *testing.T) { m := &mock.MockSharesService{} app := &App{DB: &sql.DB{}, ShareSvc: m} req := httptest.NewRequest(http.MethodGet, "/shares/nfs", nil) w := httptest.NewRecorder() app.SharesNFSHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d; body: %s", w.Code, w.Body.String()) } } func TestCreateNFSHandler(t *testing.T) { m := &mock.MockSharesService{} app := &App{DB: &sql.DB{}, ShareSvc: m} form := "name=data&path=tank/ds&options={}" // simple form body req := httptest.NewRequest(http.MethodPost, "/shares/nfs/create", strings.NewReader(form)) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("X-Auth-User", "admin") req.Header.Set("X-Auth-Role", "admin") w := httptest.NewRecorder() app.CreateNFSHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d; body: %s", w.Code, w.Body.String()) } } func TestNFSStatusHandler(t *testing.T) { m := &mock.MockSharesService{} app := &App{DB: &sql.DB{}, ShareSvc: m} req := httptest.NewRequest(http.MethodGet, "/api/shares/nfs/status", nil) w := httptest.NewRecorder() app.NFSStatusHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d; body: %s", w.Code, w.Body.String()) } } func TestSharesSMBHandler(t *testing.T) { m := &mock.MockSharesService{} app := &App{DB: &sql.DB{}, ShareSvc: m} req := httptest.NewRequest(http.MethodGet, "/shares/smb", nil) w := httptest.NewRecorder() app.SharesSMBHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d; body: %s", w.Code, w.Body.String()) } } func TestCreateSMBHandler(t *testing.T) { m := &mock.MockSharesService{} app := &App{DB: &sql.DB{}, ShareSvc: m} form := "name=smb1&path=tank/ds&allowed_users=user1,user2&read_only=1" req := httptest.NewRequest(http.MethodPost, "/shares/smb/create", strings.NewReader(form)) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("X-Auth-User", "admin") req.Header.Set("X-Auth-Role", "admin") w := httptest.NewRecorder() app.CreateSMBHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d; body: %s", w.Code, w.Body.String()) } } func TestDeleteSMBHandler(t *testing.T) { m := &mock.MockSharesService{} app := &App{DB: &sql.DB{}, ShareSvc: m} form := "id=smb-1" req := httptest.NewRequest(http.MethodPost, "/shares/smb/delete", strings.NewReader(form)) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("X-Auth-User", "admin") req.Header.Set("X-Auth-Role", "admin") w := httptest.NewRecorder() app.DeleteSMBHandler(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d; body: %s", w.Code, w.Body.String()) } }