80 lines
2.8 KiB
Go
80 lines
2.8 KiB
Go
package httpserver
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.yuntuo.hk/k2safe/orbit/internal/fault"
|
|
core "git.yuntuo.hk/k2safe/orbit/model"
|
|
"git.yuntuo.hk/k2safe/orbit/platform/auth"
|
|
"git.yuntuo.hk/k2safe/orbit/pulse/service"
|
|
)
|
|
|
|
type batchAuthStore struct {
|
|
service.Store
|
|
authCalls int
|
|
}
|
|
|
|
func batchHTTPToken(t *testing.T) string {
|
|
t.Helper()
|
|
token, _, err := auth.Issue(core.ID(strings.Repeat("1", 32)), core.ID(strings.Repeat("2", 32)))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return "Bearer " + token
|
|
}
|
|
|
|
func (s *batchAuthStore) AuthorizeSubmit(context.Context, auth.Token) error {
|
|
s.authCalls++
|
|
return fault.Unauthorized
|
|
}
|
|
|
|
func TestBatchHTTPRejectsWholeMalformedEnvelopeBeforeWrites(t *testing.T) {
|
|
for _, test := range []struct{ body, key, code string }{
|
|
{`{"items":[{"idempotency_key":"a","task":{}},{"idempotency_key":"b","task":{"unexpected":1}}]}`, "", "INVALID_ARGUMENT"},
|
|
{`{"items":[{"idempotency_key":"a","task":{"retry":{"MaxAttempts":1}}}]}`, "", "INVALID_ARGUMENT"},
|
|
{`{"items":[{"idempotency_key":"a","task":{"payload":{"x":1,"x":2}}}]}`, "", "INVALID_ARGUMENT"},
|
|
{`{"items":[null]}`, "", "INVALID_ARGUMENT"},
|
|
{`{"items":[{"idempotency_key":"a","task":null}]}`, "", "INVALID_ARGUMENT"},
|
|
{`{"items":[{"idempotency_key":"a","task":{}},{"idempotency_key":"a","task":{}}]}`, "", "INVALID_ARGUMENT"},
|
|
{`{"items":[]}`, "", "INVALID_ARGUMENT"},
|
|
{`{"items":[{"idempotency_key":"a","task":{}}]}`, "whole-batch", "INVALID_ARGUMENT"},
|
|
{`{"items":[{"idempotency_key":"a","task":{"payload":"` + strings.Repeat("x", 512<<10) + `"}}]}`, "", "BODY_TOO_LARGE"},
|
|
} {
|
|
s := &batchAuthStore{}
|
|
h := New("", nil, service.New(s)).Handler
|
|
r := httptest.NewRequest("POST", "/v1/tasks:batch", strings.NewReader(test.body))
|
|
r.Header.Set("Content-Type", "application/json")
|
|
r.Header.Set("Authorization", batchHTTPToken(t))
|
|
if test.key != "" {
|
|
r.Header.Set("Idempotency-Key", test.key)
|
|
}
|
|
w := httptest.NewRecorder()
|
|
h.ServeHTTP(w, r)
|
|
var got struct {
|
|
Error struct {
|
|
Code string `json:"code"`
|
|
} `json:"error"`
|
|
}
|
|
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil || got.Error.Code != test.code || s.authCalls != 0 {
|
|
t.Fatalf("got=%s auth=%d want=%s", w.Body.String(), s.authCalls, test.code)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBatchHTTPAuthenticatesAllInvalidItems(t *testing.T) {
|
|
s := &batchAuthStore{}
|
|
r := httptest.NewRequest("POST", "/v1/tasks:batch", strings.NewReader(`{"items":[{"idempotency_key":"a","task":{}}]}`))
|
|
r.Header.Set("Content-Type", "application/json")
|
|
r.Header.Set("Authorization", batchHTTPToken(t))
|
|
w := httptest.NewRecorder()
|
|
New("", nil, service.New(s)).Handler.ServeHTTP(w, r)
|
|
if w.Code != http.StatusUnauthorized || s.authCalls != 1 {
|
|
t.Fatal(w.Body.String(), s.authCalls)
|
|
}
|
|
}
|