package synthesis import ( "context" "testing" "bindbox-game/internal/repository/mysql" "gorm.io/driver/sqlite" "gorm.io/gorm" ) func newSynthesisServiceForTest(t *testing.T) *service { t.Helper() db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) if err != nil { t.Fatalf("open sqlite failed: %v", err) } if err := db.Exec(` CREATE TABLE product_categories ( id INTEGER PRIMARY KEY AUTOINCREMENT, is_fragment INTEGER NOT NULL DEFAULT 0, deleted_at DATETIME NULL ); `).Error; err != nil { t.Fatalf("create product_categories failed: %v", err) } if err := db.Exec(` CREATE TABLE products ( id INTEGER PRIMARY KEY AUTOINCREMENT, category_id INTEGER NOT NULL DEFAULT 0, deleted_at DATETIME NULL ); `).Error; err != nil { t.Fatalf("create products failed: %v", err) } return New(mysql.NewTestRepo(db)).(*service) } func TestValidateRecipeProducts_TargetCannotBeFragment(t *testing.T) { svc := newSynthesisServiceForTest(t) ctx := context.Background() if err := svc.repo.GetDbW().Exec("INSERT INTO product_categories(id, is_fragment) VALUES (1, 1), (2, 0)").Error; err != nil { t.Fatalf("seed categories failed: %v", err) } if err := svc.repo.GetDbW().Exec("INSERT INTO products(id, category_id) VALUES (10, 1), (11, 1)").Error; err != nil { t.Fatalf("seed products failed: %v", err) } err := svc.validateRecipeProducts(ctx, 10, []MaterialInput{{FragmentProductID: 11, RequiredCount: 1}}) if err == nil || err.Error() != "target_product_cannot_be_fragment" { t.Fatalf("expected target_product_cannot_be_fragment, got: %v", err) } } func TestValidateRecipeProducts_MaterialMustBeFragment(t *testing.T) { svc := newSynthesisServiceForTest(t) ctx := context.Background() if err := svc.repo.GetDbW().Exec("INSERT INTO product_categories(id, is_fragment) VALUES (1, 1), (2, 0)").Error; err != nil { t.Fatalf("seed categories failed: %v", err) } if err := svc.repo.GetDbW().Exec("INSERT INTO products(id, category_id) VALUES (20, 2), (21, 2)").Error; err != nil { t.Fatalf("seed products failed: %v", err) } err := svc.validateRecipeProducts(ctx, 20, []MaterialInput{{FragmentProductID: 21, RequiredCount: 1}}) want := "material_must_be_fragment:21" if err == nil || err.Error() != want { t.Fatalf("expected %s, got: %v", want, err) } } func TestValidateRecipeProducts_ValidCombination(t *testing.T) { svc := newSynthesisServiceForTest(t) ctx := context.Background() if err := svc.repo.GetDbW().Exec("INSERT INTO product_categories(id, is_fragment) VALUES (1, 1), (2, 0)").Error; err != nil { t.Fatalf("seed categories failed: %v", err) } if err := svc.repo.GetDbW().Exec("INSERT INTO products(id, category_id) VALUES (30, 2), (31, 1)").Error; err != nil { t.Fatalf("seed products failed: %v", err) } err := svc.validateRecipeProducts(ctx, 30, []MaterialInput{{FragmentProductID: 31, RequiredCount: 2}}) if err != nil { t.Fatalf("expected nil error, got: %v", err) } }