package service import ( "errors" "regexp" "testing" "time" "github.com/DATA-DOG/go-sqlmock" "github.com/wmms/wmms/internal/model" "github.com/wmms/wmms/pkg/database" ) func TestMaterialServiceRejectsInvalidCategory(t *testing.T) { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("open sql mock: %v", err) } t.Cleanup(func() { database.DB = nil db.Close() }) database.DB = db query := `SELECT EXISTS( SELECT 1 FROM material_categories WHERE id = ? AND organization_id = ? AND parent_id IS NOT NULL AND status = 'active' )` mock.ExpectQuery(regexp.QuoteMeta(query)).WithArgs(int64(12), int64(1)). WillReturnRows(sqlmock.NewRows([]string{"exists"}).AddRow(false)) categoryID := int64(12) _, err = NewMaterialService().Create(&model.CreateMaterialRequest{ OrganizationID: 1, MaterialCode: "MAT-001", Name: "轴承", CategoryID: &categoryID, }, "tester") if !errors.Is(err, ErrInvalidMaterialCategory) { t.Fatalf("create error = %v, want ErrInvalidMaterialCategory", err) } if err := mock.ExpectationsWereMet(); err != nil { t.Fatal(err) } } func TestMaterialServiceTreatsObsoleteMaterialAsInactive(t *testing.T) { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("open sql mock: %v", err) } t.Cleanup(func() { database.DB = nil db.Close() }) database.DB = db query := `SELECT id, organization_id, material_code, name, material_image, spec, manufacturer_model, category_id, base_unit_id, unit, status, version, created_at, updated_at FROM materials WHERE id = ?` now := time.Date(2026, 9, 20, 9, 0, 0, 0, time.UTC) mock.ExpectQuery(regexp.QuoteMeta(query)).WithArgs(int64(7)).WillReturnRows( sqlmock.NewRows([]string{"id", "organization_id", "material_code", "name", "material_image", "spec", "manufacturer_model", "category_id", "base_unit_id", "unit", "status", "version", "created_at", "updated_at"}). AddRow(7, 1, "MAT-007", "轴承", nil, "6205", nil, 12, 3, "件", "obsolete", 1, now, now), ) active, err := NewMaterialService().IsActive(7) if err != nil { t.Fatalf("check material activity: %v", err) } if active { t.Fatal("obsolete material must not be active") } if err := mock.ExpectationsWereMet(); err != nil { t.Fatal(err) } }