package projectinstance import ( "context" "errors" "sync" "testing" ) func TestActivationToken_OneTimeUse(t *testing.T) { ctx := context.Background() store := newMemStore() _ = SeedProjectMeta(store, 200, LifecyclePlanning, "", 1, 0) svc := NewService(store, testResolver(), nil, nil) _, _ = svc.SaveWorkflowPlan(ctx, 200, 1, true, SavePlanInput{ Plan: validPlan(), ExpectedPlanRevision: 0, ExpectedSelectionVersion: 1, }) preview, err := svc.ActivationPreview(ctx, 200, 1, true) if err != nil { t.Fatalf("ActivationPreview: %v", err) } _, err = svc.Activate(ctx, 200, 1, true, ActivateInput{ ConfirmationToken: preview.ConfirmationToken, ExpectedProjectVersion: preview.ExpectedProjectVersion, ExpectedPlanRevision: preview.ExpectedPlanRevision, }) if err != nil { t.Fatalf("first activate: %v", err) } _, err = svc.Activate(ctx, 200, 1, true, ActivateInput{ ConfirmationToken: preview.ConfirmationToken, ExpectedProjectVersion: preview.ExpectedProjectVersion, ExpectedPlanRevision: preview.ExpectedPlanRevision, }) if !errors.Is(err, ErrTokenInvalid) && !errors.Is(err, ErrPlanFrozen) { t.Fatalf("expected ErrTokenInvalid or ErrPlanFrozen on reuse, got %v", err) } } func TestActivationToken_ConcurrentActivateOnlyOneSucceeds(t *testing.T) { ctx := context.Background() store := newMemStore() _ = SeedProjectMeta(store, 201, LifecyclePlanning, "", 1, 0) svc := NewService(store, testResolver(), nil, nil) _, _ = svc.SaveWorkflowPlan(ctx, 201, 1, true, SavePlanInput{ Plan: validPlan(), ExpectedPlanRevision: 0, ExpectedSelectionVersion: 1, }) preview, err := svc.ActivationPreview(ctx, 201, 1, true) if err != nil { t.Fatalf("ActivationPreview: %v", err) } var wg sync.WaitGroup successes := 0 var mu sync.Mutex for i := 0; i < 3; i++ { wg.Add(1) go func() { defer wg.Done() _, actErr := svc.Activate(ctx, 201, 1, true, ActivateInput{ ConfirmationToken: preview.ConfirmationToken, ExpectedProjectVersion: preview.ExpectedProjectVersion, ExpectedPlanRevision: preview.ExpectedPlanRevision, }) if actErr == nil { mu.Lock() successes++ mu.Unlock() } }() } wg.Wait() if successes != 1 { t.Fatalf("expected exactly 1 successful activation, got %d", successes) } }