114 lines
6.2 KiB
Go
114 lines
6.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.cin.su/m/Assistant/contracts/continuity"
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
continuitydomain "git.cin.su/m/Assistant/modules/continuity/domain"
|
|
)
|
|
|
|
func TestCreatorResponseEndpointAppliesCompleteThroughContinuitySemantics(t *testing.T) {
|
|
core := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/v1/creator/sessions/current" || r.Header.Get("Authorization") != "Bearer ok" {
|
|
t.Fatal("unexpected identity validation")
|
|
}
|
|
_ = json.NewEncoder(w).Encode(identity.CreatorSession{ActorID: "actor-1", PrincipalID: "principal-1"})
|
|
}))
|
|
defer core.Close()
|
|
identityClient, err := newCreatorIdentityClient(core.URL, core.Client())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
repository := &fakeResponseRepository{candidates: []continuitydomain.ResponseCandidate{{
|
|
Attention: continuity.AttentionItem{ID: "attention-1", OwnerPrincipalID: "principal-1", ScopeID: "scope-1", SourceKind: continuity.AttentionSourceProspectiveReminder, SourceProspectiveID: "prospective-1", State: continuity.AttentionDelivered, Summary: "проверить базу", Revision: 1},
|
|
Prospective: continuity.ProspectiveItem{ID: "prospective-1", OwnerPrincipalID: "principal-1", ScopeID: "scope-1", State: continuity.ProspectiveDelivered, Summary: "проверить базу", Revision: 1},
|
|
}}}
|
|
mux := http.NewServeMux()
|
|
registerCreatorResponseRoute(mux, identityClient, repository, func() time.Time { return time.Unix(100, 0) })
|
|
request := httptest.NewRequest(http.MethodPost, "/v1/creator/responses", strings.NewReader(`{"SourceUtteranceID":"utterance-1","SourceIntentID":"intent-1","Message":"Готово","RequestedAtUnixMillis":100000}`))
|
|
request.Header.Set("Authorization", "Bearer ok")
|
|
recorder := httptest.NewRecorder()
|
|
mux.ServeHTTP(recorder, request)
|
|
if recorder.Code != http.StatusCreated || repository.applied.Operation != continuity.ResponseComplete || repository.applied.Outcome != continuity.ResponseOutcomeUserReportedComplete {
|
|
t.Fatalf("status=%d applied=%#v body=%s", recorder.Code, repository.applied, recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestCreatorResponseEndpointRecordsAmbiguousWithoutSilentTargetMutation(t *testing.T) {
|
|
core := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
_ = json.NewEncoder(w).Encode(identity.CreatorSession{ActorID: "actor-1", PrincipalID: "principal-1"})
|
|
}))
|
|
defer core.Close()
|
|
identityClient, err := newCreatorIdentityClient(core.URL, core.Client())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
repository := &fakeResponseRepository{candidates: []continuitydomain.ResponseCandidate{
|
|
{Attention: continuity.AttentionItem{ID: "attention-1", SourceProspectiveID: "prospective-1", State: continuity.AttentionDelivered, Summary: "первое"}},
|
|
{Attention: continuity.AttentionItem{ID: "attention-2", SourceProspectiveID: "prospective-2", State: continuity.AttentionDelivered, Summary: "второе"}},
|
|
}}
|
|
mux := http.NewServeMux()
|
|
registerCreatorResponseRoute(mux, identityClient, repository, func() time.Time { return time.Unix(100, 0) })
|
|
request := httptest.NewRequest(http.MethodPost, "/v1/creator/responses", strings.NewReader(`{"SourceUtteranceID":"utterance-1","SourceIntentID":"intent-1","Message":"Готово","RequestedAtUnixMillis":100000}`))
|
|
request.Header.Set("Authorization", "Bearer ok")
|
|
recorder := httptest.NewRecorder()
|
|
mux.ServeHTTP(recorder, request)
|
|
if recorder.Code != http.StatusCreated || repository.applied.ResolutionState != continuity.ResponseAmbiguous || repository.applied.TargetAttentionID != "" {
|
|
t.Fatalf("status=%d applied=%#v body=%s", recorder.Code, repository.applied, recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestCreatorResponseEndpointContinuesDelegationAttentionViaNaturalMessage(t *testing.T) {
|
|
core := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
_ = json.NewEncoder(w).Encode(identity.CreatorSession{ActorID: "actor-1", PrincipalID: "principal-1"})
|
|
}))
|
|
defer core.Close()
|
|
identityClient, err := newCreatorIdentityClient(core.URL, core.Client())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
repository := &fakeResponseRepository{candidates: []continuitydomain.ResponseCandidate{
|
|
{Attention: continuity.AttentionItem{
|
|
ID: "work:delegation:delegation-1",
|
|
OwnerPrincipalID: "principal-1",
|
|
ScopeID: "scope-1",
|
|
SourceKind: continuity.AttentionSourceAgentDelegation,
|
|
SourceExternalRef: "work:delegation:delegation-1",
|
|
State: continuity.AttentionPending,
|
|
Summary: "Нужен твой выбор по задаче coding-agent: docs/PROJECT_STATUS.md",
|
|
Revision: 1,
|
|
}},
|
|
{Attention: continuity.AttentionItem{ID: "attention-1", SourceProspectiveID: "prospective-1", State: continuity.AttentionDelivered, Summary: "старое напоминание"}},
|
|
}}
|
|
mux := http.NewServeMux()
|
|
registerCreatorResponseRoute(mux, identityClient, repository, func() time.Time { return time.Unix(100, 0) })
|
|
request := httptest.NewRequest(http.MethodPost, "/v1/creator/responses", strings.NewReader(`{"SourceUtteranceID":"utterance-1","SourceIntentID":"intent-1","Message":"Продолжай задачу coding-agent по docs/PROJECT_STATUS.md","RequestedAtUnixMillis":100000}`))
|
|
request.Header.Set("Authorization", "Bearer ok")
|
|
recorder := httptest.NewRecorder()
|
|
mux.ServeHTTP(recorder, request)
|
|
if recorder.Code != http.StatusCreated || repository.applied.Operation != continuity.ResponseContinue || repository.applied.TargetExternalRef != "work:delegation:delegation-1" || repository.applied.Outcome != continuity.ResponseOutcomeContinued {
|
|
t.Fatalf("status=%d applied=%#v body=%s", recorder.Code, repository.applied, recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
type fakeResponseRepository struct {
|
|
candidates []continuitydomain.ResponseCandidate
|
|
applied continuity.HumanResponse
|
|
}
|
|
|
|
func (f *fakeResponseRepository) ResponseCandidates(context.Context, identity.PrincipalID, int) ([]continuitydomain.ResponseCandidate, error) {
|
|
return f.candidates, nil
|
|
}
|
|
|
|
func (f *fakeResponseRepository) ApplyHumanResponse(_ context.Context, response continuity.HumanResponse) error {
|
|
f.applied = response
|
|
return nil
|
|
}
|