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

93 lines
3.7 KiB
Go
Raw Permalink 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 (
"net/http/httptest"
"strings"
"testing"
)
func TestSlugFromTitle(t *testing.T) {
cases := map[string]string{
"Я в сад": "ya-v-sad",
"Здоровый ЖКТ": "zdorovyy-zhkt",
"Мне год (1–2 года)": "mne-god-1-2-goda",
" Чек-ап «Я подросток»! ": "chek-ap-ya-podrostok",
"Подъезд, щука": "podezd-shchuka",
"EMSELLA 2026": "emsella-2026",
"!!!": "",
}
for title, want := range cases {
if got := slugFromTitle(title); got != want {
t.Errorf("slugFromTitle(%q) = %q, want %q", title, got, want)
}
}
}
func decodePromoBody(body string) (int, string) {
w := httptest.NewRecorder()
r := httptest.NewRequest("POST", "/api/v1/admin/promos", strings.NewReader(body))
if _, valid := decodePromo(w, r); valid {
return 200, ""
}
return w.Code, w.Body.String()
}
func TestDecodePromoRules(t *testing.T) {
cases := []struct {
name string
body string
wantCode int
wantText string
}{
{"valid published promo", `{"title":"Я в сад","discount_percent":20,"terms":"Скидка на программу чек-апа","ends_at":"2026-12-31","published":true}`, 200, ""},
{"draft without terms is allowed", `{"title":"Черновик","published":false}`, 200, ""},
{"no title", `{"title":" ","published":false}`, 422, "название"},
{"published without terms", `{"title":"Я в сад","published":true}`, 422, "условия"},
{"discount without end date", `{"title":"Я в сад","discount_percent":20,"terms":"x","published":true}`, 422, "последний день"},
{"discount out of range", `{"title":"Я в сад","discount_percent":150,"published":false}`, 422, "от 1 до 99"},
{"end before start", `{"title":"Я в сад","starts_at":"2026-10-01","ends_at":"2026-09-01","published":false}`, 422, "раньше начала"},
{"bad date", `{"title":"Я в сад","ends_at":"31.12.2026","published":false}`, 422, "ГГГГ-ММ-ДД"},
{"bad slug", `{"title":"Я в сад","slug":"Я в сад","published":false}`, 422, "латинские"},
}
for _, tc := range cases {
code, body := decodePromoBody(tc.body)
if code != tc.wantCode || (tc.wantText != "" && !strings.Contains(body, tc.wantText)) {
t.Errorf("%s: got %d %s, want %d containing %q", tc.name, code, body, tc.wantCode, tc.wantText)
}
}
}
func decodeCheckupBody(body string) (int, string, int) {
w := httptest.NewRecorder()
r := httptest.NewRequest("POST", "/api/v1/admin/checkups", strings.NewReader(body))
in, valid := decodeCheckup(w, r)
if valid {
return 200, "", len(in.Items)
}
return w.Code, w.Body.String(), 0
}
func TestDecodeCheckupRules(t *testing.T) {
code, body, items := decodeCheckupBody(`{"name":"Здоровая девочка","audience":"kids","price":5000,"old_price":6000,"items":["УЗИ"," ","Ферритин"]}`)
if code != 200 || items != 2 {
t.Fatalf("valid checkup rejected or empty items kept: %d %s items=%d", code, body, items)
}
cases := []struct {
name string
body string
wantText string
}{
{"unknown audience", `{"name":"X","audience":"pets"}`, "для кого"},
{"old price not above price", `{"name":"X","audience":"adults","price":5000,"old_price":5000}`, "больше цены"},
{"old price without price", `{"name":"X","audience":"adults","old_price":5000}`, "больше цены"},
{"negative price", `{"name":"X","audience":"adults","price":-1}`, "отрицательной"},
}
for _, tc := range cases {
code, body, _ := decodeCheckupBody(tc.body)
if code != 422 || !strings.Contains(body, tc.wantText) {
t.Errorf("%s: got %d %s, want 422 containing %q", tc.name, code, body, tc.wantText)
}
}
}