mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 08:23:45 +00:00
feat: add workload-authenticated result API
This commit is contained in:
@@ -34,6 +34,19 @@ type probeRecorderSpy struct {
|
||||
}
|
||||
}
|
||||
|
||||
type resultSubmitterSpy struct {
|
||||
calls int
|
||||
err error
|
||||
key string
|
||||
result domain.MatchResult
|
||||
}
|
||||
|
||||
func (r *resultSubmitterSpy) SubmitResult(_ context.Context, key string, result domain.MatchResult, _ domain.WorkloadBinding, _ []byte, _ time.Time) error {
|
||||
r.calls++
|
||||
r.key, r.result = key, result
|
||||
return r.err
|
||||
}
|
||||
|
||||
func (p *probeRecorderSpy) RecordProbe(_ context.Context, player, region string, rtt time.Duration, _ time.Time) error {
|
||||
p.calls++
|
||||
p.last.player, p.last.region, p.last.rtt = player, region, rtt
|
||||
@@ -916,6 +929,40 @@ func TestRankedProfileAPIReturnsBackendTierAndHidesCasualData(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerResultAPIRequiresBoundWorkloadAndDelegatesDurableSubmission(t *testing.T) {
|
||||
now := time.Unix(1000, 0).UTC()
|
||||
binding := domain.WorkloadBinding{MatchID: "match-1", ServerID: "server-1"}
|
||||
submitter := &resultSubmitterSpy{}
|
||||
service := &Service{Now: func() time.Time { return now }, WorkloadVerify: func(token string, at time.Time) (domain.WorkloadBinding, error) {
|
||||
if token != "workload-token" || !at.Equal(now) {
|
||||
t.Fatalf("verifier input=%q %v", token, at)
|
||||
}
|
||||
return binding, nil
|
||||
}, ResultSubmitter: submitter}
|
||||
server := httptest.NewServer(service.Handler())
|
||||
defer server.Close()
|
||||
body := `{"match_id":"match-1","result_nonce":"nonce-1234567890","score":{"team_0":3,"team_1":2},"integrity_state":"CERTIFIED"}`
|
||||
req, _ := http.NewRequest(http.MethodPost, server.URL+"/v1/servers/server-1/result", strings.NewReader(body))
|
||||
req.Header.Set("Authorization", "Bearer workload-token")
|
||||
req.Header.Set("Idempotency-Key", "result-key-123456")
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
if err != nil || response.StatusCode != http.StatusAccepted {
|
||||
t.Fatalf("status=%v err=%v", response.StatusCode, err)
|
||||
}
|
||||
response.Body.Close()
|
||||
if submitter.calls != 1 || submitter.key != "result-key-123456" || submitter.result.Team0Score != 3 {
|
||||
t.Fatalf("submission=%+v calls=%d", submitter, submitter.calls)
|
||||
}
|
||||
req, _ = http.NewRequest(http.MethodPost, server.URL+"/v1/servers/server-2/result", strings.NewReader(body))
|
||||
req.Header.Set("Authorization", "Bearer workload-token")
|
||||
req.Header.Set("Idempotency-Key", "result-key-123456")
|
||||
response, err = http.DefaultClient.Do(req)
|
||||
if err != nil || response.StatusCode != http.StatusUnauthorized {
|
||||
t.Fatalf("wrong server status=%v err=%v", response.StatusCode, err)
|
||||
}
|
||||
response.Body.Close()
|
||||
}
|
||||
|
||||
func TestProbeAPIUsesServerEvidenceAndRejectsClientRTTField(t *testing.T) {
|
||||
now := time.Unix(1000, 0).UTC()
|
||||
sessions := domain.NewSessionStore()
|
||||
|
||||
Reference in New Issue
Block a user