feat: add authenticated proposal API

This commit is contained in:
Josh Creek
2026-08-31 21:17:15 +01:00
parent 77c01dc531
commit 8d1b407bb0
3 changed files with 101 additions and 5 deletions
+40
View File
@@ -111,3 +111,43 @@ func TestQueueAPIRejectsUnauthenticatedUnknownAndOversizedInput(t *testing.T) {
}
_ = response.Body.Close()
}
func TestAuthenticatedProposalAPIUsesRevisionAndIdempotencyPolicy(t *testing.T) {
now := time.Unix(1000, 0).UTC()
sessions := domain.NewSessionStore()
session, token, err := sessions.Issue("player-a", time.Hour, now)
if err != nil {
t.Fatal(err)
}
proposal, err := domain.NewProposal("proposal-123456789", domain.Casual, []string{"player-a", "player-b"}, now)
if err != nil {
t.Fatal(err)
}
service := &Service{Sessions: sessions, Proposals: map[string]*domain.Proposal{proposal.ProposalID: &proposal}, Now: func() time.Time { return now }}
server := httptest.NewServer(service.Handler())
defer server.Close()
req, _ := http.NewRequest(http.MethodPost, server.URL+"/v1/proposals/"+proposal.ProposalID+"/accept", nil)
req.Header.Set("Authorization", "Bearer "+session.SessionID+":"+token)
req.Header.Set("Idempotency-Key", "proposal-response-123456")
req.Header.Set("If-Match-Revision", "0")
response, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if response.StatusCode != http.StatusOK {
t.Fatalf("proposal accept status = %d", response.StatusCode)
}
_ = response.Body.Close()
req, _ = http.NewRequest(http.MethodPost, server.URL+"/v1/proposals/"+proposal.ProposalID+"/accept", nil)
req.Header.Set("Authorization", "Bearer "+session.SessionID+":"+token)
req.Header.Set("Idempotency-Key", "proposal-response-654321")
req.Header.Set("If-Match-Revision", "0")
response, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if response.StatusCode != http.StatusConflict {
t.Fatalf("stale proposal response status = %d", response.StatusCode)
}
_ = response.Body.Close()
}