Files
Bridge-and-Join-s/internal/lkgateway/manual_test.go
T

161 lines
6.8 KiB
Go

package lkgateway
import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
)
func manualTestOrder() *ManualOrder {
return &ManualOrder{
Status: "draft", PaperNo: "15", PaperDate: "2026-09-17", ReceivedVia: "лично в офисе",
LastName: "Иванов", FirstName: "Иван", MiddleName: "Иванович", BirthDate: "1980-01-02",
DocType: "21", DocSeries: "0000", DocNumber: "000000", Account: "СЧЁТ-1",
RecvINN: "7702165310", RecvName: "Депозитарий", SettlePlace: "nrd",
Securities: []ManualSec{{ISIN: "RU0009029540", Qty: "10"}},
}
}
func TestManualSendBlockers(t *testing.T) {
rc, err := NewRuntimeConfig(t.TempDir() + "/setup.json")
if err != nil {
t.Fatal(err)
}
o := manualTestOrder()
b := manualSendBlockers(rc, o)
if len(b) != len(manualPreChecks)+1 { // все отметки + способ блокировки в QUIK
t.Fatalf("без отметок: %v", b)
}
o.Checks = map[string]ManualMark{}
for _, c := range manualPreChecks {
o.Checks[c.Key] = ManualMark{Done: true}
}
o.QuikMode = "manual"
if b = manualSendBlockers(rc, o); len(b) != 1 || !strings.Contains(b[0], "номер поручения") {
t.Fatalf("ручная блокировка без номера: %v", b)
}
o.QuikInstr = "123"
if b = manualSendBlockers(rc, o); len(b) != 0 {
t.Fatalf("всё заполнено: %v", b)
}
o.QuikMode = "auto" // цикл QUIK не включён
if b = manualSendBlockers(rc, o); len(b) != 1 {
t.Fatalf("автоблокировка недоступна: %v", b)
}
o.QuikMode = "none"
o.Securities = []ManualSec{{ISIN: "US0378331005", Qty: "0"}}
if b = manualSendBlockers(rc, o); len(b) != 2 {
t.Fatalf("иностранная бумага и нулевое количество: %v", b)
}
o.Securities = []ManualSec{{ISIN: "RU0009029540", Qty: "1"}, {ISIN: "RU000A0JUR61", Qty: "1"}}
if b = manualSendBlockers(rc, o); len(b) != 1 || !strings.Contains(b[0], "одна бумага") {
t.Fatalf("одно поручение — одна бумага: %v", b)
}
}
func TestManualQtyAndClaim(t *testing.T) {
if q, ok := manualQty("1,5"); !ok || q.Fractional != "1.5" {
t.Fatalf("дробное: %+v", q)
}
if q, ok := manualQty("7"); !ok || q.Whole != 7 {
t.Fatalf("целое: %+v", q)
}
if _, ok := manualQty("-1"); ok {
t.Fatal("отрицательное")
}
rc, _ := NewRuntimeConfig(t.TempDir() + "/setup.json")
c, err := manualClaim(rc, manualTestOrder())
if err != nil || c.ClientAccount != "СЧЁТ-1" || c.Investor.BirthDate != "1980-01-02" || c.Securities[0].SecurityCode != "RU0009029540" || c.CostInfo.No == nil {
t.Fatalf("заявка: %+v %v", c, err)
}
}
// Страницы раздела: список, форма, карточка черновика, отметки, отказ, печать.
func TestManualPages(t *testing.T) {
saved := globalManual
globalManual = loadManualStore(t.TempDir() + "/manual.json")
defer func() { globalManual = saved }()
rc, err := NewRuntimeConfig(t.TempDir() + "/setup.json")
if err != nil {
t.Fatal(err)
}
mux := http.NewServeMux()
registerManual(mux, rc, nil)
do := func(method, path string, form url.Values) *httptest.ResponseRecorder {
var req *http.Request
if form != nil {
req = httptest.NewRequest(method, path, strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
} else {
req = httptest.NewRequest(method, path, nil)
}
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
return rec
}
if rec := do("GET", "/admin/help/manual", nil); rec.Code != 200 || !strings.Contains(rec.Body.String(), "Порядок работы") {
t.Fatalf("инструкция: %d", rec.Code)
}
if rec := do("GET", "/admin/manual/new", nil); rec.Code != 200 || !strings.Contains(rec.Body.String(), "Новое поручение") {
t.Fatalf("форма: %d %s", rec.Code, rec.Body.String())
}
form := url.Values{"paper_no": {"15"}, "paper_date": {"2026-09-17"}, "last_name": {"Иванов"}, "first_name": {"Иван"},
"birth_date": {"1980-01-02"}, "doc_type": {"21"}, "doc_series": {"00 00"}, "doc_number": {"000000"}, "account": {"счёт-1"},
"recv_inn": {"7702165310"}, "sec_isin": {"ru0009029540", ""}, "sec_qty": {"10", ""}, "sec_code": {"", ""}, "sec_name": {"", ""}, "do": {"save"}}
rec := do("POST", "/admin/manual/save", form)
if rec.Code != http.StatusSeeOther || !strings.HasPrefix(rec.Header().Get("Location"), "/admin/manual/1") {
t.Fatalf("сохранение: %d %s", rec.Code, rec.Header().Get("Location"))
}
o, _ := globalManual.Get(1)
if o.DocSeries != "0000" || o.Account != "СЧЁТ-1" || len(o.Securities) != 1 || o.Securities[0].ISIN != "RU0009029540" {
t.Fatalf("данные: %+v", o)
}
if rec = do("GET", "/admin/manual/1", nil); rec.Code != 200 || !strings.Contains(rec.Body.String(), "Отправить пока нельзя") {
t.Fatalf("карточка: %d %s", rec.Code, rec.Body.String())
}
chk := url.Values{"quik_mode": {"none"}}
for _, c := range manualPreChecks {
chk.Set("check_"+c.Key, "1")
}
do("POST", "/admin/manual/1/checks", chk)
o, _ = globalManual.Get(1)
if len(manualSendBlockers(rc, o)) != 0 || o.Checks["paper"].At.IsZero() {
t.Fatalf("отметки: %+v %v", o.Checks, manualSendBlockers(rc, o))
}
if rec = do("GET", "/admin/manual/1", nil); !strings.Contains(rec.Body.String(), "Все проверки и отметки пройдены") {
t.Fatalf("готово к отправке: %s", rec.Body.String())
}
// Изменение данных сбрасывает отметки.
form.Set("id", "1")
form.Set("sec_qty", "11")
do("POST", "/admin/manual/save", form)
if o, _ = globalManual.Get(1); len(o.Checks) != 0 {
t.Fatalf("отметки должны сброситься: %+v", o.Checks)
}
do("POST", "/admin/manual/1/decline", url.Values{"reason": {"нет подписи клиента"}})
o, _ = globalManual.Get(1)
if o.Status != "declined" || o.DeclinedAt.Before(time.Now().Add(-time.Minute)) {
t.Fatalf("отказ: %+v", o)
}
for _, p := range []string{"/admin/manual", "/admin/manual/1", "/admin/manual/1/print"} {
if rec = do("GET", p, nil); rec.Code != 200 || !strings.Contains(rec.Body.String(), "нет подписи клиента") && p != "/admin/manual" {
t.Fatalf("%s: %d %s", p, rec.Code, rec.Body.String())
}
}
}
func TestOrgIdentity(t *testing.T) {
var s Settings
s.NSD.DeponentCode = "MC0000000001"
if orgCode(s) != "MC0000000001" {
t.Fatalf("код по депозитарному коду: %q", orgCode(s))
}
s.NSD.OrgCode, s.NSD.OrgINN, s.NSD.OrgName = "mc0000000002", "7700000000", "Депозитарий"
if orgCode(s) != "MC0000000002" || orgINN(s) != "7700000000" || transferringINN(s) != "7700000000" || orgName(s) != "Депозитарий" {
t.Fatalf("организация из настроек: %q %q %q", orgCode(s), orgINN(s), orgName(s))
}
}