chore: initialize go-sip repository
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.ipao.vip/rogee/go-sip/contracts"
|
||||
"git.ipao.vip/rogee/go-sip/internal/store"
|
||||
)
|
||||
|
||||
func setupHandler(t *testing.T) (*Handler, *store.Store) {
|
||||
t.Helper()
|
||||
s, err := store.Open(":memory:")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
raw, err := contracts.Read("examples/call.execute.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := s.IngestCommand(raw, "agent-call.tenant.tenant-demo-key.call.execute"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
h := &Handler{Store: s, BearerToken: "test-token"}
|
||||
t.Cleanup(func() { _ = s.Close() })
|
||||
return h, s
|
||||
}
|
||||
|
||||
func request(h http.Handler, method, path, body string) *httptest.ResponseRecorder {
|
||||
r := httptest.NewRequest(method, path, strings.NewReader(body))
|
||||
r.Header.Set("Authorization", "Bearer test-token")
|
||||
r.Header.Set("X-Tenant-ID", "tenant-demo")
|
||||
r.Header.Set("X-Request-ID", "req-1")
|
||||
r.Header.Set("Idempotency-Key", "idem-1")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, r)
|
||||
return w
|
||||
}
|
||||
|
||||
func TestControlEndpointUsesCASAndStrictJSON(t *testing.T) {
|
||||
h, _ := setupHandler(t)
|
||||
w := request(h, http.MethodPost, "/internal/v1/outbound/tasks/task-demo/controls", `{"command_id":"ctrl-1","action":"pause","expected_task_revision":1,"reason":"operator"}`)
|
||||
if w.Code != http.StatusAccepted {
|
||||
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
w = request(h, http.MethodPost, "/internal/v1/outbound/tasks/task-demo/controls", `{"command_id":"ctrl-2","action":"resume","expected_task_revision":99,"reason":"stale"}`)
|
||||
if w.Code != http.StatusConflict {
|
||||
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
w = request(h, http.MethodPost, "/internal/v1/outbound/tasks/task-demo/controls", `{"command_id":"ctrl-3","action":"pause","expected_task_revision":1,"reason":"operator","extra":true}`)
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("strict JSON status=%d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandQueryAndReplayAreTenantScopedAndDurable(t *testing.T) {
|
||||
h, s := setupHandler(t)
|
||||
w := request(h, http.MethodGet, "/internal/v1/outbound/commands/cmd_demo_001", "")
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("query status=%d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
var body map[string]any
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil || body["command_id"] != "cmd_demo_001" || body["task_id"] != "task-demo" || body["execution_id"] != "exec_demo_001" || body["aggregate_version"] != float64(1) {
|
||||
t.Fatalf("query body=%s err=%v", w.Body.String(), err)
|
||||
}
|
||||
w = request(h, http.MethodPost, "/internal/v1/outbound/commands/cmd_demo_001/replays", `{"command_id":"replay-1","reason":"repair"}`)
|
||||
if w.Code != http.StatusAccepted {
|
||||
t.Fatalf("replay status=%d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
rows, err := s.DB().Query(`SELECT status FROM outbox WHERE event_id = 'replay-idem-1'`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
if !rows.Next() {
|
||||
t.Fatal("replay was not persisted to outbox")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user