package main import ( "context" "errors" "testing" "time" "github.com/Wei-Shaw/sub2api/internal/config" "github.com/Wei-Shaw/sub2api/internal/handler" "github.com/Wei-Shaw/sub2api/internal/service" "github.com/stretchr/testify/require" ) func TestProvideServiceBuildInfo(t *testing.T) { in := handler.BuildInfo{ Version: "v-test", BuildType: "release", } out := provideServiceBuildInfo(in) require.Equal(t, in.Version, out.Version) require.Equal(t, in.BuildType, out.BuildType) } func TestProvideCleanup_WithMinimalDependencies_NoPanic(t *testing.T) { cfg := &config.Config{} oauthSvc := service.NewOAuthService(nil, nil) openAIOAuthSvc := service.NewOpenAIOAuthService(nil, nil) geminiOAuthSvc := service.NewGeminiOAuthService(nil, nil, nil, nil, cfg) antigravityOAuthSvc := service.NewAntigravityOAuthService(nil) tokenRefreshSvc := service.NewTokenRefreshService( nil, oauthSvc, openAIOAuthSvc, geminiOAuthSvc, antigravityOAuthSvc, nil, nil, cfg, nil, ) accountExpirySvc := service.NewAccountExpiryService(nil, time.Second) subscriptionExpirySvc := service.NewSubscriptionExpiryService(nil, time.Second) pricingSvc := service.NewPricingService(cfg, nil) emailQueueSvc := service.NewEmailQueueService(nil, 1) billingCacheSvc := service.NewBillingCacheService(nil, nil, nil, nil, cfg) idempotencyCleanupSvc := service.NewIdempotencyCleanupService(nil, cfg) schedulerSnapshotSvc := service.NewSchedulerSnapshotService(nil, nil, nil, nil, cfg) opsSystemLogSinkSvc := service.NewOpsSystemLogSink(nil) cleanup := provideCleanup( nil, // entClient nil, // redis &service.OpsMetricsCollector{}, &service.OpsAggregationService{}, &service.OpsAlertEvaluatorService{}, &service.OpsCleanupService{}, &service.OpsScheduledReportService{}, opsSystemLogSinkSvc, schedulerSnapshotSvc, tokenRefreshSvc, accountExpirySvc, subscriptionExpirySvc, &service.UsageCleanupService{}, idempotencyCleanupSvc, pricingSvc, emailQueueSvc, billingCacheSvc, &service.UsageRecordWorkerPool{}, &service.SubscriptionService{}, oauthSvc, openAIOAuthSvc, geminiOAuthSvc, antigravityOAuthSvc, nil, // openAIGateway nil, // scheduledTestRunner nil, // backupSvc nil, // paymentOrderExpiry ) require.NotPanics(t, func() { cleanup() }) } func TestNewBootstrapFunc_RunsDefaultsBeforeRecovery(t *testing.T) { cfg := &config.Config{} order := make([]string, 0, 2) bootstrap := newBootstrapFunc( func(context.Context) error { order = append(order, "defaults") return nil }, func(_ context.Context, gotRepo service.UserRepository, got *config.Config) error { require.Nil(t, gotRepo) require.Same(t, cfg, got) order = append(order, "recover") return nil }, nil, cfg, ) require.NoError(t, bootstrap()) require.Equal(t, []string{"defaults", "recover"}, order) } func TestNewBootstrapFunc_StopsWhenDefaultsFail(t *testing.T) { cfg := &config.Config{} wantErr := errors.New("defaults failed") recoverCalled := false bootstrap := newBootstrapFunc( func(context.Context) error { return wantErr }, func(context.Context, service.UserRepository, *config.Config) error { recoverCalled = true return nil }, nil, cfg, ) require.ErrorIs(t, bootstrap(), wantErr) require.False(t, recoverCalled) }