69 lines
2.5 KiB
Go
69 lines
2.5 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"dana/internal/onec"
|
|
)
|
|
|
|
func postEvent(a *API, key, body string) *httptest.ResponseRecorder {
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/onec/events", strings.NewReader(body))
|
|
if key != "" {
|
|
req.Header.Set("X-Api-Key", key)
|
|
}
|
|
rec := httptest.NewRecorder()
|
|
a.onecEvents(rec, req)
|
|
return rec
|
|
}
|
|
|
|
func TestOnecEventsAuthAndValidation(t *testing.T) {
|
|
a := &API{limiter: newRateLimiter(), onec: onec.New("http://127.0.0.1:1", "k", "X-Api-Key")}
|
|
|
|
if rec := postEvent(a, "secret", `{"event":"schedule_changed"}`); rec.Code != http.StatusNotFound {
|
|
t.Fatalf("вебхук без ключа в настройках должен быть выключен, получили %d", rec.Code)
|
|
}
|
|
|
|
a.WithOneCWebhook("secret")
|
|
if rec := postEvent(a, "", `{"event":"schedule_changed"}`); rec.Code != http.StatusUnauthorized {
|
|
t.Fatalf("без ключа: %d", rec.Code)
|
|
}
|
|
if rec := postEvent(a, "wrong", `{"event":"schedule_changed"}`); rec.Code != http.StatusUnauthorized {
|
|
t.Fatalf("неверный ключ: %d", rec.Code)
|
|
}
|
|
if rec := postEvent(a, "secret", `{"event":"nope"}`); rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("неизвестное событие: %d", rec.Code)
|
|
}
|
|
if rec := postEvent(a, "secret", `{"event":"appointment_status","appointment_id":"A-1","status":"weird"}`); rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("неверный статус: %d", rec.Code)
|
|
}
|
|
if rec := postEvent(a, "secret", `{"event":"appointment_status","status":"cancelled"}`); rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("нет номера записи: %d", rec.Code)
|
|
}
|
|
if rec := postEvent(a, "secret", `not json`); rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("битый JSON: %d", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestOnecEventsBruteForceLimit(t *testing.T) {
|
|
a := &API{limiter: newRateLimiter(), onec: onec.New("http://127.0.0.1:1", "k", "X-Api-Key")}
|
|
a.WithOneCWebhook("secret")
|
|
var last int
|
|
for i := 0; i < 25; i++ {
|
|
last = postEvent(a, "guess", `{}`).Code
|
|
}
|
|
if last != http.StatusTooManyRequests {
|
|
t.Fatalf("перебор ключа должен упираться в лимит, получили %d", last)
|
|
}
|
|
}
|
|
|
|
func TestAutonomousWebhookValidationWithoutBridge(t *testing.T) {
|
|
a := &API{limiter: newRateLimiter()}
|
|
a.WithOneCWebhook("secret")
|
|
if rec := postEvent(a, "secret", `{"event":"unsupported"}`); rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("bridge-free route disabled: %d", rec.Code)
|
|
}
|
|
}
|