893e1222ab
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
103 lines
3.9 KiB
Go
103 lines
3.9 KiB
Go
package quikexport
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// Пакеты: набор таблиц, обратное определение пакетов, обязательный Portfolio.
|
|
func TestQuikExportPackages(t *testing.T) {
|
|
tabs := quikExportPackageTables([]string{"positions", "refs"})
|
|
for _, want := range []string{"Portfolio", "DepoLimits", "MoneyLimits", "Securities", "SecDepoAccount"} {
|
|
if !slices.Contains(tabs, want) {
|
|
t.Fatalf("нет %s в %v", want, tabs)
|
|
}
|
|
}
|
|
if slices.Contains(tabs, "AllTrades") {
|
|
t.Fatalf("лишняя таблица рынка: %v", tabs)
|
|
}
|
|
if got := quikExportPackageTables(nil); len(got) != 1 || got[0] != "Portfolio" {
|
|
t.Fatalf("без пакетов остаётся только Portfolio: %v", got)
|
|
}
|
|
pk := quikExportPackagesOf(tabs)
|
|
if !slices.Contains(pk, "positions") || !slices.Contains(pk, "refs") || !slices.Contains(pk, "risk") {
|
|
t.Fatalf("обратное определение: %v", pk)
|
|
}
|
|
if slices.Contains(pk, "deals") {
|
|
t.Fatalf("пакет сделок не выбран: %v", pk)
|
|
}
|
|
// Каждая таблица пакета есть в каталоге экспортёра.
|
|
known := map[string]bool{}
|
|
for _, tb := range quikExportTables {
|
|
known[tb.Name] = true
|
|
}
|
|
for _, p := range quikExportPackages {
|
|
for _, tb := range p.Tables {
|
|
if !known[tb] {
|
|
t.Errorf("пакет %s: таблицы %s нет в каталоге", p.Key, tb)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Старая настройка (preset=depo) переносится в пакеты.
|
|
func TestQuikExportPresetMigration(t *testing.T) {
|
|
s := QuikExportSettings{Preset: "depo"}.withDefaults()
|
|
if s.Preset != "packages" || len(s.Packages) == 0 {
|
|
t.Fatalf("миграция набора: %+v", s.Packages)
|
|
}
|
|
if !slices.Contains(s.Tables, "DepoLimits") || !slices.Contains(s.Tables, "Portfolio") {
|
|
t.Fatalf("таблицы после миграции: %v", s.Tables)
|
|
}
|
|
}
|
|
|
|
// Раздел настроек рисует пакеты и сохраняет выбор.
|
|
func TestQuikExportPackagesSection(t *testing.T) {
|
|
dir := t.TempDir()
|
|
keyPath := filepath.Join(dir, "module.key")
|
|
if err := os.WriteFile(keyPath, []byte(testKey+"\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
srv, err := New(Config{StorePath: filepath.Join(dir, "settings.json"), SetupPath: filepath.Join(dir, "setup.json"), KeyPath: keyPath})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
h := srv.Handler()
|
|
req := httptest.NewRequest(http.MethodGet, "/section", nil)
|
|
req.Header.Set("X-BJ-Module-Key", testKey)
|
|
req.Header.Set("X-BJ-Licensed", "1")
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("раздел: %d %s", rec.Code, rec.Body.String())
|
|
}
|
|
for _, want := range []string{"Какие данные выгружаем", "Позиции и деньги клиента", "Цены для оценки портфеля", "Личный кабинет"} {
|
|
if !strings.Contains(rec.Body.String(), want) {
|
|
t.Errorf("в разделе нет %q", want)
|
|
}
|
|
}
|
|
form := url.Values{"part": {"volume"}, "mode": {"packages"}, "packages": {"risk", "positions", "prices"},
|
|
"portfolio_period": {"60"}, "param_period": {"30"}, "limit_kinds": {"0, 1, 365"}, "debug_level": {"1"}}
|
|
req = httptest.NewRequest(http.MethodPost, "/admin/setup/quikexport", strings.NewReader(form.Encode()))
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
req.Header.Set("X-BJ-Module-Key", testKey)
|
|
rec = httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusNoContent {
|
|
t.Fatalf("сохранение: %d", rec.Code)
|
|
}
|
|
s := srv.store.Get()
|
|
if s.Preset != "packages" || !slices.Contains(s.Tables, "DepoLimits") || !slices.Contains(s.Tables, "Params") {
|
|
t.Fatalf("после сохранения: %v %v", s.Preset, s.Tables)
|
|
}
|
|
if slices.Contains(s.Tables, "Trades") {
|
|
t.Fatalf("пакет сделок не выбирали: %v", s.Tables)
|
|
}
|
|
}
|