package handlers import ( "encoding/json" "net/http" "net/http/httptest" "path/filepath" "testing" "time" "git.mchus.pro/mchus/quoteforge/internal/localdb" "github.com/gin-gonic/gin" ) func TestPricelistGetItems_ReturnsLotCategoryFromLocalPricelistItems(t *testing.T) { gin.SetMode(gin.TestMode) local, err := localdb.New(filepath.Join(t.TempDir(), "local.db")) if err != nil { t.Fatalf("init local db: %v", err) } t.Cleanup(func() { _ = local.Close() }) if err := local.SaveLocalPricelist(&localdb.LocalPricelist{ ServerID: 1, Source: "estimate", Version: "S-2026-02-11-001", Name: "test", CreatedAt: time.Now(), SyncedAt: time.Now(), IsUsed: false, }); err != nil { t.Fatalf("save local pricelist: %v", err) } localPL, err := local.GetLocalPricelistByServerID(1) if err != nil { t.Fatalf("get local pricelist: %v", err) } if err := local.SaveLocalPricelistItems([]localdb.LocalPricelistItem{ { PricelistID: localPL.ID, LotName: "NO_UNDERSCORE_NAME", LotCategory: "CPU", Price: 10, }, }); err != nil { t.Fatalf("save local pricelist items: %v", err) } h := NewPricelistHandler(local) req, _ := http.NewRequest("GET", "/api/pricelists/1/items?page=1&per_page=50", nil) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = req c.Params = gin.Params{{Key: "id", Value: "1"}} h.GetItems(c) if w.Code != http.StatusOK { t.Fatalf("expected status 200, got %d: %s", w.Code, w.Body.String()) } var resp struct { Items []struct { LotName string `json:"lot_name"` Category string `json:"category"` UnitPrice any `json:"price"` } `json:"items"` } if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("unmarshal response: %v", err) } if len(resp.Items) != 1 { t.Fatalf("expected 1 item, got %d", len(resp.Items)) } if resp.Items[0].LotName != "NO_UNDERSCORE_NAME" { t.Fatalf("expected lot_name NO_UNDERSCORE_NAME, got %q", resp.Items[0].LotName) } if resp.Items[0].Category != "CPU" { t.Fatalf("expected category CPU, got %q", resp.Items[0].Category) } } func TestPricelistList_ActiveOnlyExcludesPricelistsWithoutItems(t *testing.T) { gin.SetMode(gin.TestMode) local, err := localdb.New(filepath.Join(t.TempDir(), "local_active_only.db")) if err != nil { t.Fatalf("init local db: %v", err) } t.Cleanup(func() { _ = local.Close() }) if err := local.SaveLocalPricelist(&localdb.LocalPricelist{ ServerID: 10, Source: "estimate", Version: "E-1", Name: "with-items", CreatedAt: time.Now().Add(-time.Minute), SyncedAt: time.Now().Add(-time.Minute), }); err != nil { t.Fatalf("save with-items pricelist: %v", err) } withItems, err := local.GetLocalPricelistByServerID(10) if err != nil { t.Fatalf("load with-items pricelist: %v", err) } if err := local.SaveLocalPricelistItems([]localdb.LocalPricelistItem{ { PricelistID: withItems.ID, LotName: "CPU_X", LotCategory: "CPU", Price: 100, }, }); err != nil { t.Fatalf("save with-items pricelist items: %v", err) } if err := local.SaveLocalPricelist(&localdb.LocalPricelist{ ServerID: 11, Source: "estimate", Version: "E-2", Name: "without-items", CreatedAt: time.Now(), SyncedAt: time.Now(), }); err != nil { t.Fatalf("save without-items pricelist: %v", err) } h := NewPricelistHandler(local) req, _ := http.NewRequest("GET", "/api/pricelists?source=estimate&active_only=true", nil) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = req h.List(c) if w.Code != http.StatusOK { t.Fatalf("expected status 200, got %d: %s", w.Code, w.Body.String()) } var resp struct { Pricelists []struct { ID uint `json:"id"` } `json:"pricelists"` Total int `json:"total"` } if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("unmarshal response: %v", err) } if resp.Total != 1 { t.Fatalf("expected total=1, got %d", resp.Total) } if len(resp.Pricelists) != 1 { t.Fatalf("expected 1 pricelist, got %d", len(resp.Pricelists)) } if resp.Pricelists[0].ID != 10 { t.Fatalf("expected pricelist id=10, got %d", resp.Pricelists[0].ID) } }