mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-12 15:43:43 +00:00
feat: add participant-scoped proposal recovery
This commit is contained in:
@@ -505,3 +505,53 @@ func TestProbeAPIUsesServerEvidenceAndRejectsClientRTTField(t *testing.T) {
|
||||
}
|
||||
_ = response.Body.Close()
|
||||
}
|
||||
|
||||
func TestProposalRecoveryIsParticipantScopedAndExpiresAtReadBoundary(t *testing.T) {
|
||||
now := time.Unix(1000, 0).UTC()
|
||||
sessions := domain.NewSessionStore()
|
||||
owner, ownerToken, err := sessions.Issue("player-a", time.Hour, now)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
other, otherToken, err := sessions.Issue("player-z", time.Hour, now)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
proposal, err := domain.NewProposal("proposal-recovery", domain.Casual, []string{"player-a", "player-b"}, now)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
current := now
|
||||
service := &Service{Sessions: sessions, Proposals: map[string]*domain.Proposal{proposal.ProposalID: &proposal}, Now: func() time.Time { return current }}
|
||||
server := httptest.NewServer(service.Handler())
|
||||
defer server.Close()
|
||||
get := func(session domain.Session, token string) (int, proposalResponse) {
|
||||
req, _ := http.NewRequest(http.MethodGet, server.URL+"/v1/proposals/proposal-recovery", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+session.SessionID+":"+token)
|
||||
response, requestErr := http.DefaultClient.Do(req)
|
||||
if requestErr != nil {
|
||||
t.Fatal(requestErr)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
var body proposalResponse
|
||||
if response.StatusCode == http.StatusOK {
|
||||
if err := json.NewDecoder(response.Body).Decode(&body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
return response.StatusCode, body
|
||||
}
|
||||
status, recovered := get(owner, ownerToken)
|
||||
if status != http.StatusOK || recovered.State != string(domain.Open) || recovered.Revision != 0 {
|
||||
t.Fatalf("owner recovery status=%d body=%+v", status, recovered)
|
||||
}
|
||||
status, _ = get(other, otherToken)
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("non-participant recovery status=%d, want 404", status)
|
||||
}
|
||||
current = now.Add(domain.ProposalWindow)
|
||||
status, recovered = get(owner, ownerToken)
|
||||
if status != http.StatusOK || recovered.State != string(domain.Expired) || recovered.Revision != 1 {
|
||||
t.Fatalf("expired recovery status=%d body=%+v", status, recovered)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user