dana-medical-site/internal/api/booking_confirm_test.go
2026-10-14 13:33:13 +00:00

107 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"strings"
"testing"
"time"
"dana/internal/bitrix"
"dana/internal/storage"
)
func TestConfirmDeadline(t *testing.T) {
cfg := storage.DefaultBookingSettings // 24 ч после записи или 2 ч до приёма
created := time.Date(2026, 10, 9, 22, 0, 0, 0, moscow)
cases := []struct {
name string
start time.Time
want time.Time
}{
{"приём через три дня — 24 ч после записи", created.Add(72 * time.Hour), created.Add(24 * time.Hour)},
{"приём завтра утром — за 2 ч до приёма", created.Add(12 * time.Hour), created.Add(10 * time.Hour)},
{"приём через час — не раньше 30 минут после записи", created.Add(time.Hour), created.Add(30 * time.Minute)},
}
for _, c := range cases {
got, ok := confirmDeadline(created, c.start, cfg)
if !ok || !got.Equal(c.want) {
t.Errorf("%s: срок %v, ждали %v", c.name, got, c.want)
}
}
if _, ok := confirmDeadline(created, created.Add(72*time.Hour), storage.BookingSettings{}); ok {
t.Error("оба правила выключены — автоотмены быть не должно")
}
}
func TestDecideConfirm(t *testing.T) {
cfg := storage.DefaultBookingSettings
created := time.Date(2026, 10, 9, 10, 0, 0, 0, moscow)
start := created.Add(48 * time.Hour)
soon := created.Add(time.Hour)
late := created.Add(25 * time.Hour) // срок (24 ч) прошёл, приём ещё впереди
cases := []struct {
name string
semantic string
now time.Time
want confirmAction
}{
{"оператор подтвердил", bitrix.SemanticSuccess, soon, confirmOK},
{"оператор отменил", bitrix.SemanticFailure, soon, confirmCancel},
{"в работе, срок не вышел", bitrix.SemanticProcess, soon, confirmWait},
{"лид удалён, срок не вышел", "", soon, confirmWait},
{"в работе, срок вышел", bitrix.SemanticProcess, late, confirmExpire},
{"подтвердили даже после срока — подтверждаем", bitrix.SemanticSuccess, late, confirmOK},
{"провал после начала приёма — в 1С не трогаем", bitrix.SemanticFailure, start.Add(time.Minute), confirmMissed},
{"никто не ответил до приёма — в 1С не трогаем", bitrix.SemanticProcess, start, confirmMissed},
}
for _, c := range cases {
if got := decideConfirm(c.semantic, created, start, c.now, cfg); got != c.want {
t.Errorf("%s: %v, ждали %v", c.name, got, c.want)
}
}
if got := decideConfirm(bitrix.SemanticProcess, created, start, late, storage.BookingSettings{}); got != confirmWait {
t.Errorf("автоотмена выключена: %v, ждали ожидание", got)
}
}
func TestLeadOnlyDraftAsksToBookManually(t *testing.T) {
it := storage.ConfirmItem{
Start: time.Date(2026, 10, 12, 15, 30, 0, 0, moscow), Patient: "Анна", Phone: "+7 928 000 00 00",
DoctorName: "Петрова <script>", OnecID: "",
}
d := leadOnlyDraft(it)
if !strings.HasPrefix(d.Title, "Заявка на запись: ") || d.SourceID != bitrixSiteSourceID || d.Phone != "+79280000000" {
t.Errorf("заголовок/источник/телефон: %+v", d)
}
for _, want := range []string{"НЕ закреплено", "запишите его в 1С вручную", "12.10.2026 в 15:30", "&lt;script&gt;"} {
if !strings.Contains(d.Comments, want) {
t.Errorf("в комментарии нет %q: %q", want, d.Comments)
}
}
if strings.Contains(d.Comments, "<script>") || strings.Contains(d.Comments, "№ записи в 1С") {
t.Errorf("лишнее в комментарии: %q", d.Comments)
}
}
func TestLeadDraftEscapesPatientInput(t *testing.T) {
it := storage.ConfirmItem{
Start: time.Date(2026, 10, 12, 15, 30, 0, 0, moscow), CreatedAt: time.Date(2026, 10, 9, 10, 0, 0, 0, moscow),
Patient: "Анна", Phone: "8 (928) 000-00-00", DoctorName: "Иванов <b>И.</b>", Branch: "ул. Ленина, 1",
ServiceName: "Консультация", OnecID: "A-17",
}
d := leadDraft(it, storage.DefaultBookingSettings)
if d.Phone != "+79280000000" {
t.Errorf("телефон не нормализован: %q", d.Phone)
}
if strings.Contains(d.Comments, "<b>") || !strings.Contains(d.Comments, "&lt;b&gt;") {
t.Errorf("HTML пациента/врача не экранирован: %q", d.Comments)
}
for _, want := range []string{"12.10.2026 в 15:30", "A-17", "Консультация", "Клиент записался", "отменится автоматически 10.10 в 10:00"} {
if !strings.Contains(d.Comments, want) {
t.Errorf("в комментарии нет %q: %q", want, d.Comments)
}
}
if d.SourceID != bitrixSiteSourceID || !strings.HasPrefix(d.Title, "Онлайн-запись: ") {
t.Errorf("источник/заголовок: %+v", d)
}
}