package m2mcore_test import ( "context" "errors" "testing" "git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2m" "git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2mcore" ) func newTestDeal(t *testing.T) *m2mcore.Deal { t.Helper() guid, err := m2mcore.NewUUIDv4() if err != nil { t.Fatalf("UUID: %v", err) } d, err := m2mcore.NewDeal(m2m.UUID(guid), "00000000-0000-0000-0000-000000000001", []byte("")) if err != nil { t.Fatalf("NewDeal: %v", err) } return d } func TestFSMAllowedTransitions(t *testing.T) { cases := []struct { from m2mcore.State to m2mcore.State ok bool }{ {m2mcore.StateDraft, m2mcore.StateValidated, true}, {m2mcore.StateDraft, m2mcore.StateSubmittedToNSD, false}, {m2mcore.StateValidated, m2mcore.StateSubmittedToNSD, true}, {m2mcore.StateAwaitingDecision, m2mcore.StateConfirmed, true}, {m2mcore.StateAwaitingDecision, m2mcore.StateRejected, true}, {m2mcore.StateAwaitingDecision, m2mcore.StateTimedOut, true}, {m2mcore.StateConfirmed, m2mcore.StateAwaitingSUB16, true}, {m2mcore.StateDone, m2mcore.StateRejected, false}, {m2mcore.StateRejected, m2mcore.StateDone, false}, } for _, c := range cases { if got := m2mcore.CanTransition(c.from, c.to); got != c.ok { t.Errorf("CanTransition(%s,%s)=%v ожидалось %v", c.from, c.to, got, c.ok) } } } func TestFSMIsTerminal(t *testing.T) { for _, s := range []m2mcore.State{m2mcore.StateDone, m2mcore.StateRejected, m2mcore.StateTimedOut} { if !m2mcore.IsTerminal(s) { t.Errorf("%s должно быть терминальным", s) } } for _, s := range []m2mcore.State{m2mcore.StateDraft, m2mcore.StateConfirmed} { if m2mcore.IsTerminal(s) { t.Errorf("%s не должно быть терминальным", s) } } } func TestDealManualReject(t *testing.T) { d := newTestDeal(t) if err := d.SendToManualApproval(context.Background(), "ambiguous_decision"); err != nil { t.Fatalf("SendToManualApproval из Draft неожиданно дал ошибку %v", err) } } func TestDealInvalidTransition(t *testing.T) { d := newTestDeal(t) // Draft -> SubmittedToNSD не разрешён. err := d.Submit(context.Background()) if !errors.Is(err, m2mcore.ErrInvalidTransition) { t.Errorf("ожидалась ErrInvalidTransition, получено %v", err) } } func TestDealCompleteSUB16(t *testing.T) { d := newTestDeal(t) if err := d.ApproveManually(context.Background(), "operator-1"); err == nil { // Из Draft нельзя сразу ApproveManually — нужен путь через // ManualApproval. Это тоже проверяем. t.Errorf("ApproveManually из Draft должен был отказать") } if err := d.SendToManualApproval(context.Background(), "test"); err != nil { t.Fatal(err) } if err := d.ApproveManually(context.Background(), "operator-1"); err != nil { t.Fatalf("ApproveManually: %v", err) } if err := d.CompleteSUB16(context.Background()); err != nil { t.Fatalf("CompleteSUB16: %v", err) } if d.State != m2mcore.StateDone { t.Errorf("конечное состояние %s, ожидалось %s", d.State, m2mcore.StateDone) } }