117 lines
4.8 KiB
Go
117 lines
4.8 KiB
Go
package api
|
||
|
||
import (
|
||
"net/http"
|
||
"net/http/httptest"
|
||
"reflect"
|
||
"strings"
|
||
"testing"
|
||
"time"
|
||
)
|
||
|
||
func TestClinicFrom(t *testing.T) {
|
||
if c, ok := clinicFrom(""); !ok || c.Key != clinicDANA {
|
||
t.Fatalf("пустая клиника должна быть DANA: %v %v", c, ok)
|
||
}
|
||
if c, ok := clinicFrom(" Ochevidno "); !ok || c.Key != "ochevidno" {
|
||
t.Fatalf("очевидно не распознано: %v %v", c, ok)
|
||
}
|
||
if _, ok := clinicFrom("glaz"); ok {
|
||
t.Fatal("неизвестная клиника принята")
|
||
}
|
||
}
|
||
|
||
// Портал Битрикс24 общий: один источник лида не может считаться сразу в двух клиниках,
|
||
// а каналы источников должны быть известными листами отчёта.
|
||
func TestClinicBitrixSourcesDisjoint(t *testing.T) {
|
||
owner := map[string]string{}
|
||
for _, c := range clinicList {
|
||
for src, ch := range c.bitrixSources {
|
||
if prev, dup := owner[src]; dup {
|
||
t.Errorf("источник %s есть и у %s, и у %s", src, prev, c.Key)
|
||
}
|
||
owner[src] = c.Key
|
||
if _, known := knownChannels[ch]; !known {
|
||
t.Errorf("%s: источник %s ведёт в неизвестный канал %q", c.Key, src, ch)
|
||
}
|
||
}
|
||
for src := range c.bitrixGeneral {
|
||
if prev, dup := owner[src]; dup {
|
||
t.Errorf("общий источник %s уже у %s", src, prev)
|
||
}
|
||
owner[src] = c.Key
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestProdoctorovUploadPerClinic(t *testing.T) {
|
||
from := time.Date(2026, 9, 1, 0, 0, 0, 0, moscow)
|
||
to := time.Date(2026, 10, 1, 0, 0, 0, 0, moscow)
|
||
och := clinicByKey["ochevidno"]
|
||
ochFile := prodoctorovPhoneBook(t, "Офтальмологический центр «Очевидно»", "запись на приём (телефон) - сентября 2026 ",
|
||
[]string{"31", "10.09.2026 12:30", "79281230031", "нет", "500", "оплачено"})
|
||
danaFile := prodoctorovPhoneBook(t, "«Дана Медикал» на Ляхова", "запись на приём (телефон) - сентября 2026 ",
|
||
[]string{"21", "10.09.2026 12:30", "79281230021", "нет", "500", "оплачено"})
|
||
|
||
opts, err := prodoctorovUploadOptsFor(och, [][]byte{ochFile}, from, to)
|
||
if err != nil {
|
||
t.Fatalf("выгрузка «Очевидно» не принята в отчёт «Очевидно»: %v", err)
|
||
}
|
||
if got := opts.pbxLists["продокторов"]; !reflect.DeepEqual(got, []string{"9281230031"}) {
|
||
t.Fatalf("телефоны: %v", got)
|
||
}
|
||
if _, err := prodoctorovUploadOptsFor(och, [][]byte{danaFile}, from, to); err == nil ||
|
||
!strings.Contains(err.Error(), "другой клиники") || !strings.Contains(err.Error(), "«Очевидно»") {
|
||
t.Fatalf("файл DANA принят в отчёт «Очевидно»: %v", err)
|
||
}
|
||
}
|
||
|
||
func TestPBXEnvHint(t *testing.T) {
|
||
if got := pbxEnvHint(clinicDANA); got != "MEGAFON_API_URL и MEGAFON_API_KEY" {
|
||
t.Fatal(got)
|
||
}
|
||
if got := pbxEnvHint("ochevidno"); got != "OCHEVIDNO_MEGAFON_API_URL и OCHEVIDNO_MEGAFON_API_KEY" {
|
||
t.Fatal(got)
|
||
}
|
||
}
|
||
|
||
// Без токена или с коротким токеном ссылка отклоняется сразу, до обращения к базе.
|
||
func TestShareRejectsMissingToken(t *testing.T) {
|
||
a := &API{}
|
||
for _, h := range []string{"", "Bearer ", "Bearer short", "Bearer " + strings.Repeat("x", 100)} {
|
||
req := httptest.NewRequest(http.MethodGet, "/api/v1/share/weekly-reports", nil)
|
||
if h != "" {
|
||
req.Header.Set("Authorization", h)
|
||
}
|
||
rec := httptest.NewRecorder()
|
||
a.shareWeeklyReports(rec, req)
|
||
if rec.Code != http.StatusUnauthorized {
|
||
t.Fatalf("%q: код %d, ожидали 401", h, rec.Code)
|
||
}
|
||
if rec.Header().Get("Cache-Control") != "no-store" {
|
||
t.Fatalf("%q: ответ можно кешировать", h)
|
||
}
|
||
}
|
||
if shareTokenHash("a") == shareTokenHash("b") || len(shareTokenHash("a")) != 64 {
|
||
t.Fatal("хеш токена")
|
||
}
|
||
}
|
||
|
||
// Блок «Колл-ц» дашборда — совпадения колл-центра с 1С, а не вся выгрузка 1С (как в «Показателях»).
|
||
func TestWeeklyCallCenterUsesMatchedCallCenter(t *testing.T) {
|
||
sum := channelsSummary{
|
||
Totals: channelsTotals{UniqueFIO: 1021, Services: 3162, Revenue: 7997520},
|
||
Channels: []channelRow{
|
||
{Name: "Сайт", Patients: 25, Services: 33, Revenue: 215000},
|
||
{Name: knownChannels["все номера"].title, Patients: 452, Services: 1890, Revenue: 3441100, AvgCheck: 7613.05},
|
||
},
|
||
}
|
||
cc := weeklyCallCenterSales(sum)
|
||
if cc.Patients != 452 || cc.Services != 1890 || cc.Revenue != 3441100 || cc.AvgCheck != 7613.05 {
|
||
t.Fatalf("колл-центр взят не из совпадений: %+v", cc)
|
||
}
|
||
if got := weeklyCallCenterSales(channelsSummary{Totals: sum.Totals}); got.Revenue != 0 || got.Patients != 0 {
|
||
t.Fatalf("без листа колл-центра подставились итоги 1С: %+v", got)
|
||
}
|
||
}
|