92 lines
3.3 KiB
Go
92 lines
3.3 KiB
Go
package usecase
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"apps/backend/internal/module/scout/domain"
|
|
"apps/backend/internal/module/scout/repository"
|
|
)
|
|
|
|
func TestRunPublishVisibilityBarrierAndCounters(t *testing.T) {
|
|
ctx := context.Background()
|
|
store := repository.NewMemory()
|
|
run := domain.NewRun("run-publish", "job-publish", 7, domain.RunBrief{
|
|
Intent: "市集", Mode: domain.ModeActivity, TargetCount: 3,
|
|
}, 100)
|
|
if err := store.CreateRun(ctx, run); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := run.Transition(domain.RunRunning, 200); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := store.ReplaceRunGuarded(ctx, 7, run.ID, []string{domain.RunQueued}, run); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
svc := New(store)
|
|
posts := []*domain.Post{
|
|
{ID: "publish-new", RunID: run.ID, OwnerUID: 7, OutreachStatus: domain.OutreachNew, PostedAt: 200, CreatedAt: 20},
|
|
{ID: "publish-old", RunID: run.ID, OwnerUID: 7, OutreachStatus: domain.OutreachDrafted, PostedAt: 100, CreatedAt: 10},
|
|
}
|
|
if err := svc.StageRunPosts(ctx, 7, run.ID, posts); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
staged, err := store.ListRunPosts(ctx, 7, run.ID, 1, 10)
|
|
if err != nil || staged.Pagination.Total != 0 || len(staged.Items) != 0 {
|
|
t.Fatalf("staged posts leaked: %+v %v", staged, err)
|
|
}
|
|
if err := svc.PublishRun(ctx, 7, run.ID, posts); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
visible, err := store.ListRunPosts(ctx, 7, run.ID, 1, 10)
|
|
if err != nil || visible.Pagination.Total != 2 || len(visible.Items) != 2 || visible.Items[0].ID != "publish-new" {
|
|
t.Fatalf("published results=%+v %v", visible, err)
|
|
}
|
|
got, err := store.GetRun(ctx, 7, run.ID)
|
|
if err != nil || got.Status != domain.RunSucceeded || got.EligibleCount != 2 || got.PendingCount != 2 || got.ShortfallCount != 1 {
|
|
t.Fatalf("published run=%+v %v", got, err)
|
|
}
|
|
seen, err := store.HasSeenIdentity(ctx, 7, "id:publish-new")
|
|
if err != nil || !seen {
|
|
t.Fatalf("published identity not marked: %v %v", seen, err)
|
|
}
|
|
}
|
|
|
|
func TestRunPublishFailureLeavesResultsHiddenAndTerminalGuard(t *testing.T) {
|
|
ctx := context.Background()
|
|
store := repository.NewMemory()
|
|
run := domain.NewRun("run-fail", "job-fail", 7, domain.RunBrief{Intent: "市集", Mode: domain.ModeActivity}, 100)
|
|
if err := store.CreateRun(ctx, run); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := run.Transition(domain.RunRunning, 200); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := store.ReplaceRunGuarded(ctx, 7, run.ID, []string{domain.RunQueued}, run); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
svc := New(store)
|
|
posts := []*domain.Post{{ID: "hidden", RunID: run.ID, OwnerUID: 7}}
|
|
if err := svc.StageRunPosts(ctx, 7, run.ID, posts); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := svc.FailRun(ctx, 7, run.ID, "provider timeout"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
page, err := store.ListRunPosts(ctx, 7, run.ID, 1, 10)
|
|
if err != nil || page.Pagination.Total != 0 || len(page.Items) != 0 {
|
|
t.Fatalf("failed run exposed posts: %+v %v", page, err)
|
|
}
|
|
failed, err := store.GetRun(ctx, 7, run.ID)
|
|
if err != nil || failed.Status != domain.RunFailed || failed.Error != "provider timeout" {
|
|
t.Fatalf("failed run=%+v %v", failed, err)
|
|
}
|
|
if err := svc.FailRun(ctx, 7, run.ID, "retry"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := svc.StageRunPosts(ctx, 7, run.ID, posts); !errors.Is(err, domain.ErrIllegalRunStatus) {
|
|
t.Fatalf("terminal stage error=%v", err)
|
|
}
|
|
}
|