package service import ( "context" "testing" "time" "github.com/DATA-DOG/go-sqlmock" usermodel "wx_service/internal/model" ) func TestSmokeAIAdviceServiceIsAllowedMember(t *testing.T) { t.Parallel() db, mock, cleanup := newMockGormDB(t) defer cleanup() svc := &SmokeAIAdviceService{db: db} user := &usermodel.User{ID: 200, MiniProgramID: 100} adviceDate := time.Date(2026, 3, 1, 0, 0, 0, 0, time.Local) mock.ExpectQuery("SELECT count\\(\\*\\) FROM `user_memberships`"). WithArgs(uint(100), uint(200), "active", sqlmock.AnyArg()). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) allowed, err := svc.isAllowed(context.Background(), user, adviceDate) if err != nil { t.Fatalf("isAllowed: %v", err) } if !allowed { t.Fatalf("isAllowed got=false, want=true for active member") } if err := mock.ExpectationsWereMet(); err != nil { t.Fatalf("unmet expectations: %v", err) } } func TestSmokeAIAdviceServiceIsAllowedNonMemberLocked(t *testing.T) { t.Parallel() db, mock, cleanup := newMockGormDB(t) defer cleanup() svc := &SmokeAIAdviceService{db: db} user := &usermodel.User{ID: 201, MiniProgramID: 101} adviceDate := time.Date(2026, 3, 1, 0, 0, 0, 0, time.Local) mock.ExpectQuery("SELECT count\\(\\*\\) FROM `user_memberships`"). WithArgs(uint(101), uint(201), "active", sqlmock.AnyArg()). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0)) mock.ExpectQuery("SELECT \\* FROM `fa_smoke_ai_advice_unlocks`"). WithArgs(201, adviceDate.Format("2006-01-02"), sqlmock.AnyArg()). WillReturnRows(sqlmock.NewRows([]string{"id", "uid", "unlock_date", "ad_watched_at"})) allowed, err := svc.isAllowed(context.Background(), user, adviceDate) if err != nil { t.Fatalf("isAllowed: %v", err) } if allowed { t.Fatalf("isAllowed got=true, want=false for non-member locked user") } if err := mock.ExpectationsWereMet(); err != nil { t.Fatalf("unmet expectations: %v", err) } } func TestSmokeAINextSmokeServiceIsAllowedNonMemberUnlocked(t *testing.T) { t.Parallel() db, mock, cleanup := newMockGormDB(t) defer cleanup() svc := &SmokeAINextSmokeService{db: db} user := &usermodel.User{ID: 202, MiniProgramID: 102} planDate := time.Date(2026, 3, 1, 0, 0, 0, 0, time.Local) mock.ExpectQuery("SELECT count\\(\\*\\) FROM `user_memberships`"). WithArgs(uint(102), uint(202), "active", sqlmock.AnyArg()). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0)) mock.ExpectQuery("SELECT \\* FROM `fa_smoke_ai_advice_unlocks`"). WithArgs(202, planDate.Format("2006-01-02"), sqlmock.AnyArg()). WillReturnRows(sqlmock.NewRows([]string{"id", "uid", "unlock_date", "ad_watched_at"}). AddRow(1, 202, planDate, time.Now())) allowed, err := svc.isAllowed(context.Background(), user, planDate) if err != nil { t.Fatalf("isAllowed: %v", err) } if !allowed { t.Fatalf("isAllowed got=false, want=true for non-member unlocked user") } if err := mock.ExpectationsWereMet(); err != nil { t.Fatalf("unmet expectations: %v", err) } }