package job import ( "context" "testing" "img_infinite_canvas/internal/domain/design" "github.com/hibiken/asynq" ) type fakeJobProcessor struct { job design.Job failedJob design.Job failure error } func (p *fakeJobProcessor) ProcessJob(ctx context.Context, job design.Job) error { p.job = job return nil } func (p *fakeJobProcessor) HandleJobFailure(ctx context.Context, job design.Job, err error) error { p.failedJob = job p.failure = err return nil } func TestAsynqWorkerDispatchesJobPayload(t *testing.T) { processor := &fakeJobProcessor{} worker, err := NewAsynqWorker(AsynqOptions{}, processor) if err != nil { t.Fatal(err) } task := asynq.NewTask(string(design.JobTextExtraction), []byte(`{"Kind":"canvas:text-extraction","ProjectID":"project-1","ThreadID":"thread-1","Feature":"edit-text"}`)) if err := worker.handle(processor)(context.Background(), task); err != nil { t.Fatal(err) } if processor.job.Kind != design.JobTextExtraction || processor.job.ProjectID != "project-1" || processor.job.Feature != "edit-text" { t.Fatalf("unexpected dispatched job: %#v", processor.job) } } func TestAsynqFailureHandlerReportsVisualGenerationFailures(t *testing.T) { processor := &fakeJobProcessor{} task := asynq.NewTask(string(design.JobCreateProjectGeneration), []byte(`{"Kind":"canvas:create-project-generation","ProjectID":"project-1","ThreadID":"thread-1"}`)) failure := context.DeadlineExceeded handleAsynqTaskFailure(context.Background(), task, failure, processor) if processor.failure == nil { t.Fatal("expected visual generation failure to be reported") } if processor.failedJob.Kind != design.JobCreateProjectGeneration || processor.failedJob.ProjectID != "project-1" || processor.failedJob.ThreadID != "thread-1" { t.Fatalf("unexpected failed job: %#v", processor.failedJob) } } func TestMaxRetryForVisualGenerationJobsDisablesQueueRetry(t *testing.T) { if got := maxRetryForJob(design.Job{Kind: design.JobCreateProjectGeneration}, 3); got != 0 { t.Fatalf("expected visual generation max retry 0, got %d", got) } if got := maxRetryForJob(design.Job{Kind: design.JobMockupModelGeneration}, 3); got != 0 { t.Fatalf("expected mockup model generation max retry 0, got %d", got) } if got := maxRetryForJob(design.Job{Kind: design.JobTextExtraction}, 3); got != 3 { t.Fatalf("expected non visual generation max retry passthrough, got %d", got) } }