haixunMaster/haixun-backend/internal/model/job/usecase/dedupe_test.go

86 lines
2.2 KiB
Go
Raw Permalink Normal View History

2026-06-23 09:54:27 +00:00
package usecase
import (
"context"
"testing"
"haixun-backend/internal/model/job/domain/entity"
"haixun-backend/internal/model/job/domain/enum"
domusecase "haixun-backend/internal/model/job/domain/usecase"
)
func TestCreateRun_BlocksNonRepeatableAfterSuccess(t *testing.T) {
ctx := context.Background()
template := demoTemplate()
template.Repeatable = false
template.DedupeKeys = []string{"scope_id"}
runs := newMemoryRunRepo(nil)
queue := newMemoryQueueRepo()
uc := testUseCaseFull(template, runs, nil, queue)
first, err := uc.CreateRun(ctx, domusecase.CreateRunRequest{
TemplateType: template.Type,
Scope: "user",
ScopeID: "u1",
})
if err != nil {
t.Fatalf("first CreateRun() error = %v", err)
}
first.Status = enum.RunStatusSucceeded
first.DedupeKey = buildDedupeKey(template, "user", "u1", nil)
_, _ = runs.Update(ctx, first)
_, err = uc.CreateRun(ctx, domusecase.CreateRunRequest{
TemplateType: template.Type,
Scope: "user",
ScopeID: "u1",
})
if err == nil {
t.Fatal("expected duplicate completed job error")
}
}
func TestCreateRun_DedupeLeaseBlocksParallel(t *testing.T) {
ctx := context.Background()
template := demoTemplate()
template.Repeatable = true
template.DedupeKeys = []string{"scope_id"}
queue := newMemoryQueueRepo()
uc := testUseCaseFull(template, newMemoryRunRepo(nil), nil, queue)
first, err := uc.CreateRun(ctx, domusecase.CreateRunRequest{
TemplateType: template.Type,
Scope: "user",
ScopeID: "u1",
})
if err != nil {
t.Fatalf("first CreateRun() error = %v", err)
}
if first.Status != enum.RunStatusQueued {
t.Fatalf("first status = %s, want queued", first.Status)
}
_, err = uc.CreateRun(ctx, domusecase.CreateRunRequest{
TemplateType: template.Type,
Scope: "user",
ScopeID: "u1",
})
if err == nil {
t.Fatal("expected in-progress dedupe error")
}
}
func TestBuildDedupeKey_IncludesScopeID(t *testing.T) {
template := &entity.Template{
Type: "demo",
DedupeKeys: []string{"scope_id", "target"},
}
key1 := buildDedupeKey(template, "user", "a", map[string]any{"target": "x"})
key2 := buildDedupeKey(template, "user", "b", map[string]any{"target": "x"})
if key1 == key2 {
t.Fatal("dedupe keys should differ by scope_id")
}
}