Files
Bridge-and-Join-s/internal/lkgateway/depo_package_test.go
T
zuevav 4b62d00ac2 Входящие M2M: пакет только целиком и отказ M2M08 для бумаг «для квалифицированных инвесторов»
Сверка с DEPO: у бумаги проверяется опция RESTRICTED («Ограничение ценной бумаги по обращению»,
1 — предназначена для квалифицированных инвесторов). Если инвестор не квалифицирован — отказ M2M08;
квалифицирован по всем видам — проходит; по части видов — предупреждение, решает оператор.

Пакет принимается только целиком (решение 16.09): при отказе хотя бы по одной бумаге рекомендация —
отказ по всем с кодом первой отказной, и так же нормализуется отправляемое решение (packageDecisions);
в форме выбор отказа по одной бумаге переключает на отказ все.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 14:45:43 +03:00

74 lines
3.2 KiB
Go

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)
}
}