//go:build live package lkgateway import ( "context" "strings" "testing" "time" ) // Покрытие данных кабинета на реальных договорах: что клиент увидит на каждой странице. // Только чтение. В вывод идут номера договоров без ФИО. func TestLiveCabinetCoverage(t *testing.T) { rc, err := NewRuntimeConfig("/var/lib/bj/.bj/setup.json") if err != nil { t.Fatal(err) } globalRC = rc fs := rc.Snapshot().Fancy ctx, cancel := context.WithTimeout(context.Background(), 8*time.Minute) defer cancel() contracts, err := depoListContracts(ctx, fs, "", 60) if err != nil { t.Fatalf("список договоров: %v", err) } if len(contracts) == 0 { t.Fatal("в депозитарии нет договоров с остатками") } type agg struct{ clients, withData, rows int } var positions, priced, ops, income, corp, docs agg var posTotal, posPriced int from := time.Now().AddDate(-2, 0, 0).Format("2006-01-02") for _, c := range contracts { num := c.Contract if i := strings.Index(num, " "); i > 0 { num = num[:i] // без ФИО } pos, err := depoClientPositions(ctx, fs, c.Contract) if err != nil { t.Errorf("%s: портфель: %v", num, err) continue } positions.clients++ if len(pos) > 0 { positions.withData++ positions.rows += len(pos) } isins := make([]string, 0, len(pos)) for _, p := range pos { if p.ISIN != "" { isins = append(isins, p.ISIN) } } px := lkPrices(ctx, rc, isins) got := 0 for _, i := range isins { if p, ok := px[strings.ToUpper(i)]; ok && p.Price > 0 { got++ } } posTotal += len(isins) posPriced += got priced.clients++ if got > 0 { priced.withData++ } o, err := lkOperations(ctx, fs, c.Contract, from, "", 200) if err != nil { t.Errorf("%s: операции: %v", num, err) } ops.clients++ if len(o) > 0 { ops.withData++ ops.rows += len(o) } inc, _, err := lkIncome(ctx, fs, c.Contract, from, "") if err != nil { t.Errorf("%s: доходы: %v", num, err) } income.clients++ if len(inc) > 0 { income.withData++ income.rows += len(inc) } ca, err := lkCorpActions(ctx, fs, isins) if err != nil { t.Errorf("%s: корпоративные действия: %v", num, err) } corp.clients++ if len(ca) > 0 { corp.withData++ corp.rows += len(ca) } d, err := lkReadyDocuments(ctx, fs, c.Contract) if err != nil { t.Errorf("%s: документы: %v", num, err) } docs.clients++ if len(d) > 0 { docs.withData++ docs.rows += len(d) } } line := func(name string, a agg) { t.Logf("%-28s данные есть у %3d из %3d клиентов, строк всего %d", name, a.withData, a.clients, a.rows) } t.Logf("Выборка: %d договоров, период операций и доходов — с %s", len(contracts), from) line("Портфель (остатки)", positions) line("Оценка по ценам QUIK", priced) if posTotal > 0 { t.Logf("%-28s оценено %d из %d позиций (%.0f%%)", " доля позиций с ценой", posPriced, posTotal, 100*float64(posPriced)/float64(posTotal)) } line("Операции по счёту депо", ops) line("Доходы (купоны, дивиденды)", income) line("Корпоративные действия", corp) line("Готовые выписки", docs) }