package lkgateway
import (
"bytes"
"strings"
"testing"
"time"
)
// buildClaimDataFromView повторяет вычисления renderClaim для теста.
func buildClaimDataFromView(v ClaimView, quik []*QuikLink, fail *SendFailure) claimData {
qfISIN, qfReply := quikRegisterFailure(quik)
return claimData{
page: page{Title: "Заявка"},
Claim: v, Quik: quik, Fail: fail,
SentToNSD: claimSentToNSD(v), QuikFailISIN: qfISIN, QuikFailReply: qfReply,
QuikNoSec: quikReplyIsNoSecurities(qfReply),
}
}
func TestClaimHelpers(t *testing.T) {
sent := ClaimView{Stages: []StageView{{State: "draft"}, {State: "validated"}, {State: "submitted_to_nsd"}, {State: "awaiting_decision"}}}
if !claimSentToNSD(sent) {
t.Fatal("submitted_to_nsd должна считаться отправкой в НРД")
}
notSent := ClaimView{Stages: []StageView{{State: "draft"}, {State: "validated"}, {State: "rejected"}}}
if claimSentToNSD(notSent) {
t.Fatal("validated→rejected без submitted_to_nsd — в НРД не отправлялось")
}
for _, r := range []string{"Данный инструмент запрещен для операции шорт", "Недостаточно ценных бумаг", "короткая позиция"} {
if !quikReplyIsNoSecurities(r) {
t.Fatalf("ответ %q должен распознаваться как нехватка бумаг", r)
}
}
if quikReplyIsNoSecurities("Неизвестный депозитарий получателя") {
t.Fatal("ошибка про депозитарий — не нехватка бумаг")
}
links := []*QuikLink{{GUID: "g", ISIN: "RU0009029540", State: "error",
Err: "МНП отверг регистрацию: Данный инструмент запрещен для операции шорт",
Steps: []QuikStep{{Action: "register", Reply: "Данный инструмент запрещен для операции шорт", OK: false, At: time.Now()}}}}
isin, reply := quikRegisterFailure(links)
if isin != "RU0009029540" || !strings.Contains(reply, "шорт") {
t.Fatalf("quikRegisterFailure вернул %q / %q", isin, reply)
}
}
// Отклонена до отправки + QUIK сообщил о нехватке бумаг (как e3607d2a).
func TestClaimRenderNotSentNoSec(t *testing.T) {
a, err := newAdmin()
if err != nil {
t.Fatal(err)
}
v := ClaimView{ID: "e3607d2a-2608-441b-b49a-e99ef3e4edd1", Status: "rejected",
RequestRawXML: "",
Stages: []StageView{{State: "draft"}, {State: "validated"}, {State: "rejected"}}}
quik := []*QuikLink{{GUID: "67f09cec", ISIN: "RU0009029540", State: "error",
Err: "МНП отверг регистрацию: Данный инструмент запрещен для операции шорт",
Steps: []QuikStep{{Action: "register", Reply: "Данный инструмент запрещен для операции шорт", OK: false, At: time.Now()}}}}
var b bytes.Buffer
if err := a.claim.ExecuteTemplate(&b, "layout", buildClaimDataFromView(v, quik, nil)); err != nil {
t.Fatal(err)
}
s := b.String()
for _, want := range []string{
"В НРД ничего не отправлено", // баннер отмены до отправки
"Сформированный пакет (M2MTransferRequest)", // заголовок карточки
"в НРД не отправлен", // бейдж
"нет (недостаточно) бумаг", // карточка QUIK: нехватка
"Данный инструмент запрещен для операции шорт", // дословный ответ QUIK
} {
if !strings.Contains(s, want) {
t.Fatalf("нет %q", want)
}
}
if strings.Contains(s, "Отправленный пакет (M2MTransferRequest)") {
t.Fatal("для неотправленной заявки не должно быть заголовка «Отправленный пакет»")
}
}
// Нормально отправленная заявка — старый заголовок сохраняется, баннеров нет.
func TestClaimRenderSentOK(t *testing.T) {
a, err := newAdmin()
if err != nil {
t.Fatal(err)
}
v := ClaimView{ID: "11111111-2222-3333-4444-555555555555", Status: "awaiting_decision",
RequestRawXML: "",
Stages: []StageView{{State: "draft"}, {State: "validated"}, {State: "submitted_to_nsd"}, {State: "awaiting_decision"}}}
var b bytes.Buffer
if err := a.claim.ExecuteTemplate(&b, "layout", buildClaimDataFromView(v, nil, nil)); err != nil {
t.Fatal(err)
}
s := b.String()
if !strings.Contains(s, "Отправленный пакет (M2MTransferRequest)") {
t.Fatal("отправленная заявка должна показывать «Отправленный пакет»")
}
if strings.Contains(s, "В НРД ничего не отправлено") || strings.Contains(s, "в НРД не отправлен") {
t.Fatal("для отправленной заявки баннеры «не отправлено» показывать нельзя")
}
}