package lkgateway import ( "strings" "testing" ) // Пакет принимается только целиком: отказ по одной бумаге — отказ по всем с тем же кодом. func TestFinishResultWholePackage(t *testing.T) { res := depoResult{Secs: []depoSecResult{ {Security: "RU0009029540", Recommend: "confirm"}, {Security: "RU0007661625", Recommend: "reject", RejectCode: "M2M05"}, {Security: "RU000A0JUR61", Recommend: "confirm"}, }} finishResult(&res) if res.Recommend != "reject" || !strings.Contains(res.Summary, "отказ пакетом M2M05") { t.Fatalf("итог: %s %q", res.Recommend, res.Summary) } for _, s := range res.Secs { if s.Recommend != "reject" || s.RejectCode != "M2M05" { t.Fatalf("бумага %s: %s %s", s.Security, s.Recommend, s.RejectCode) } } if last := res.Secs[0].Checks[len(res.Secs[0].Checks)-1]; last.OK || !strings.Contains(last.Detail, "RU0007661625") { t.Fatalf("пояснение отказа пакетом: %+v", last) } ok := depoResult{Secs: []depoSecResult{{Recommend: "confirm"}, {Recommend: "confirm"}}} finishResult(&ok) if ok.Recommend != "confirm" { t.Fatalf("все бумаги прошли: %s", ok.Recommend) } } func TestPackageDecisions(t *testing.T) { in := []SecurityDecision{{ReferenceID: "A", Confirm: true}, {ReferenceID: "B", RejectCode: "M2M08"}, {ReferenceID: "C", Confirm: true}} out := packageDecisions(in) for _, d := range out { if d.Confirm || d.RejectCode != "M2M08" { t.Fatalf("частичное согласие не должно уходить: %+v", out) } } if !in[0].Confirm { t.Fatal("исходный срез не должен меняться") } all := []SecurityDecision{{ReferenceID: "A", Confirm: true}, {ReferenceID: "B", Confirm: true}} if got := packageDecisions(all); !got[0].Confirm || !got[1].Confirm { t.Fatalf("согласие по всем: %+v", got) } } func TestQualOnlyCheck(t *testing.T) { notQual := depoParty{faceOK: true, qualWarn: true, qualDet: "инвестор НЕ квалифицированный"} qualAll := depoParty{faceOK: true, qualAll: true} partial := depoParty{faceOK: true, qualDet: "инвестор — квалифицированный (опция DEPO): облигации"} const q = "бумага предназначена для квалифицированных инвесторов (опция DEPO)" if c := qualOnlyCheck(true, true, q, notQual); c.OK || c.Code != "M2M08" { t.Fatalf("неквал + бумага для квал: %+v", c) } if c := qualOnlyCheck(true, true, q, qualAll); !c.OK || c.Warn { t.Fatalf("квал по всем видам: %+v", c) } if c := qualOnlyCheck(true, true, q, partial); !c.OK || !c.Warn { t.Fatalf("квал по части видов — решает оператор: %+v", c) } if c := qualOnlyCheck(true, false, "ограничений по обращению нет (опция DEPO)", notQual); !c.OK || c.Warn { t.Fatalf("бумага без ограничений: %+v", c) } if c := qualOnlyCheck(true, true, q, depoParty{}); !c.OK { t.Fatalf("инвестор не найден — отказ даёт M2M04, не эта проверка: %+v", c) } } // Списание: бумага для квал. инвесторов у неквалифицированного у нас клиента — предупреждение, не отказ. func TestOutQualCheck(t *testing.T) { const q = "бумага предназначена для квалифицированных инвесторов (опция DEPO)" notQual := depoParty{faceOK: true, qualWarn: true, qualDet: "инвестор НЕ квалифицированный"} if c := outQualCheck(true, true, q, notQual); !c.OK || !c.Warn || c.Strict { t.Fatalf("неквал у нас отправляет бумагу для квал: %+v", c) } if c := outQualCheck(true, true, q, depoParty{faceOK: true, qualAll: true}); !c.OK || c.Warn { t.Fatalf("квал по всем видам: %+v", c) } if c := outQualCheck(true, false, "ограничений по обращению нет (опция DEPO)", notQual); !c.OK || c.Warn { t.Fatalf("бумага без ограничений — зелёный: %+v", c) } for _, c := range partyChecks(notQual, "1", "2", "x") { if strings.HasPrefix(c.Name, "Квал") { t.Fatalf("общая жёлтая строка квалификации больше не нужна: %+v", c) } } }