package testx import ( "context" "fmt" "os" "testing" jobs_args "quyun/v2/app/jobs/args" "quyun/v2/database" "quyun/v2/database/models" "quyun/v2/providers/job" "quyun/v2/providers/jwt" "quyun/v2/providers/postgres" "quyun/v2/providers/storage" "github.com/riverqueue/river" "go.ipao.vip/atom" "go.ipao.vip/atom/container" "go.ipao.vip/atom/contracts" "go.ipao.vip/atom/opt" "go.uber.org/dig" "github.com/rogeecn/fabfile" convey "github.com/smartystreets/goconvey/convey" ) func Default(providers ...container.ProviderContainer) container.Providers { return append(container.Providers{ postgres.DefaultProvider(), jwt.DefaultProvider(), job.DefaultProvider(), storage.DefaultProvider(), testJobWorkersProvider(), database.DefaultProvider(), }, providers...) } type orderRefundTestWorker struct { river.WorkerDefaults[jobs_args.OrderRefundJob] } func (w *orderRefundTestWorker) Work(_ context.Context, _ *river.Job[jobs_args.OrderRefundJob]) error { return nil } type mediaAssetProcessTestWorker struct { river.WorkerDefaults[jobs_args.MediaAssetProcessJob] } func (w *mediaAssetProcessTestWorker) Work(_ context.Context, _ *river.Job[jobs_args.MediaAssetProcessJob]) error { return nil } type notificationTestWorker struct { river.WorkerDefaults[jobs_args.NotificationArgs] } func (w *notificationTestWorker) Work(ctx context.Context, job *river.Job[jobs_args.NotificationArgs]) error { arg := job.Args n := &models.Notification{ TenantID: arg.TenantID, UserID: arg.UserID, Type: arg.Type, Title: arg.Title, Content: arg.Content, IsRead: false, } return models.NotificationQuery.WithContext(ctx).Create(n) } func testJobWorkersProvider() container.ProviderContainer { return container.ProviderContainer{ Provider: func(_ ...opt.Option) error { return container.Container.Provide(func(__job *job.Job) (contracts.Initial, error) { obj := &orderRefundTestWorker{} if err := river.AddWorkerSafely(__job.Workers, obj); err != nil { return nil, fmt.Errorf("register order refund test worker: %w", err) } obj2 := &mediaAssetProcessTestWorker{} if err := river.AddWorkerSafely(__job.Workers, obj2); err != nil { return nil, fmt.Errorf("register media process test worker: %w", err) } obj3 := ¬ificationTestWorker{} if err := river.AddWorkerSafely(__job.Workers, obj3); err != nil { return nil, fmt.Errorf("register notification test worker: %w", err) } return obj, nil }, atom.GroupInitial) }, } } func Serve(providers container.Providers, t *testing.T, invoke any) { convey.Convey("tests boot up", t, func() { baseCtx := context.Background() container.Close() container.Container = dig.New() convey.So(container.Container.Provide(func() context.Context { return baseCtx }), convey.ShouldBeNil) file := fabfile.MustFind("config.toml") localEnv := os.Getenv("ENV_LOCAL") if localEnv != "" { file = fabfile.MustFind("config." + localEnv + ".toml") } convey.So(atom.LoadProviders(file, providers), convey.ShouldBeNil) convey.So(os.Setenv("JOB_INLINE", "1"), convey.ShouldBeNil) t.Cleanup(func() { _ = os.Unsetenv("JOB_INLINE") }) convey.So(container.Container.Invoke(func(params struct { dig.In Initials []contracts.Initial `group:"initials"` Job *job.Job }, ) error { _ = params.Initials jobCtx, cancel := context.WithCancel(baseCtx) t.Cleanup(cancel) go func() { _ = params.Job.Start(jobCtx) }() return nil }), convey.ShouldBeNil) convey.So(container.Container.Invoke(invoke), convey.ShouldBeNil) }) }