package continuityexecutor import ( "encoding/json" "net/http" "net/http/httptest" "testing" commitcontract "git.cin.su/m/Assistant/contracts/commit" "git.cin.su/m/Assistant/contracts/continuity" ) func TestExecuteAndReconcileUseTypedReceipt(t *testing.T) { action := testAction() server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Authorization") != "Bearer secret" { http.Error(w, "denied", http.StatusUnauthorized) return } receipt := continuity.ActionReceipt{ ActionIntentID: continuity.CommittedActionIntentID(action.Proposal.IntentID), AuthorizedActionID: continuity.CommittedAuthorizedActionID(action.ID), OwnerPrincipalID: action.PrincipalID, Subject: action.Proposal.ContinuitySubject, ResultState: continuity.ProspectiveSatisfied, ResultRevision: 5, } _ = json.NewEncoder(w).Encode(receipt) })) defer server.Close() adapter, err := New(server.URL, "secret", server.Client()) if err != nil { t.Fatal(err) } if result := adapter.Execute(action); !result.Known || !result.Succeeded { t.Fatalf("execute result = %#v", result) } if result := adapter.Reconcile(action); !result.Known || !result.Succeeded { t.Fatalf("reconcile result = %#v", result) } } func TestAcknowledgementLossReconcilesWithoutDuplicatePost(t *testing.T) { action := testAction() posts := 0 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { posts++ hijacker, ok := w.(http.Hijacker) if !ok { t.Fatal("test server cannot simulate acknowledgement loss") } connection, _, err := hijacker.Hijack() if err != nil { t.Fatal(err) } _ = connection.Close() return } receipt := continuity.ActionReceipt{ ActionIntentID: continuity.CommittedActionIntentID(action.Proposal.IntentID), AuthorizedActionID: continuity.CommittedAuthorizedActionID(action.ID), OwnerPrincipalID: action.PrincipalID, Subject: action.Proposal.ContinuitySubject, ResultState: continuity.ProspectiveSatisfied, ResultRevision: 5, } _ = json.NewEncoder(w).Encode(receipt) })) defer server.Close() adapter, err := New(server.URL, "secret", server.Client()) if err != nil { t.Fatal(err) } if result := adapter.Execute(action); result.Known { t.Fatalf("lost acknowledgement was treated as known: %#v", result) } if result := adapter.Reconcile(action); !result.Known || !result.Succeeded { t.Fatalf("reconciliation result = %#v", result) } if posts != 1 { t.Fatalf("effect was posted %d times", posts) } } func testAction() commitcontract.AuthorizedAction { return commitcontract.AuthorizedAction{ ID: "authorized-1", PrincipalID: "principal-1", State: commitcontract.ActionAuthorized, Proposal: commitcontract.ActionProposal{ IntentID: "intent-1", CapabilityID: commitcontract.CapabilityContinuityTransition, Operation: commitcontract.OperationSatisfyDelivered, ContinuitySubject: continuity.SatisfyDeliveredSubject{ProspectiveItemID: "prospective-1", ExpectedRevision: 4, FromState: continuity.ProspectiveDelivered, ToState: continuity.ProspectiveSatisfied, EvidenceRef: "artifact://evidence/1"}, }, } }