72 lines
3.5 KiB
Go
72 lines
3.5 KiB
Go
package action_commit_test
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"git.cin.su/m/Assistant/contracts/authority"
|
|
commitcontract "git.cin.su/m/Assistant/contracts/commit"
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
"git.cin.su/m/Assistant/contracts/work"
|
|
authoritydomain "git.cin.su/m/Assistant/modules/authority/domain"
|
|
commitdomain "git.cin.su/m/Assistant/modules/commit/domain"
|
|
"git.cin.su/m/Assistant/modules/commit/ports"
|
|
"git.cin.su/m/Assistant/platform/ids"
|
|
)
|
|
|
|
type validator struct{}
|
|
|
|
func (validator) Validate(context authority.AuthorizationContext) error {
|
|
return authoritydomain.ValidateGrant(context.Binding, context.Scope, context.Grant)
|
|
}
|
|
|
|
type unknownExecutor struct{}
|
|
|
|
func (unknownExecutor) Execute(commitcontract.AuthorizedAction) ports.ExecutionResult {
|
|
return ports.ExecutionResult{Known: false}
|
|
}
|
|
|
|
func TestWS003RejectsRevokedGrantAndNeverExecutesProposalDirectly(t *testing.T) {
|
|
context, proposal := testContextAndProposal()
|
|
context.Grant.Active = false
|
|
_, err := commitdomain.Authorize(proposal, context, validator{}, commitcontract.AuthorizedActionID(ids.ID("authorized")), 1)
|
|
if !errors.Is(err, authoritydomain.ErrInvalidGrant) {
|
|
t.Fatalf("authorization error = %v, want invalid grant", err)
|
|
}
|
|
}
|
|
|
|
func TestWS003RejectsMissingActorPrincipalBinding(t *testing.T) {
|
|
context, proposal := testContextAndProposal()
|
|
context.Binding.Active = false
|
|
_, err := commitdomain.Authorize(proposal, context, validator{}, commitcontract.AuthorizedActionID(ids.ID("authorized")), 1)
|
|
if !errors.Is(err, authoritydomain.ErrInvalidGrant) {
|
|
t.Fatalf("authorization error = %v, want invalid grant", err)
|
|
}
|
|
}
|
|
|
|
func TestWS003UnknownOutcomeBlocksBlindRetry(t *testing.T) {
|
|
context, proposal := testContextAndProposal()
|
|
action, err := commitdomain.Authorize(proposal, context, validator{}, commitcontract.AuthorizedActionID(ids.ID("authorized")), 1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
attempt, err := commitdomain.Execute(action, commitcontract.ActionAttemptID(ids.ID("attempt-one")), unknownExecutor{})
|
|
if !errors.Is(err, commitdomain.ErrUnknownOutcome) || attempt.State != commitcontract.ActionUnknownOutcome {
|
|
t.Fatalf("unknown result = %#v, %v", attempt, err)
|
|
}
|
|
action.State = commitcontract.ActionUnknownOutcome
|
|
if _, err := commitdomain.Execute(action, commitcontract.ActionAttemptID(ids.ID("attempt-two")), unknownExecutor{}); !errors.Is(err, commitdomain.ErrUnknownOutcome) {
|
|
t.Fatalf("blind retry error = %v, want unknown outcome", err)
|
|
}
|
|
}
|
|
|
|
func testContextAndProposal() (commitdomain.AuthorizationContext, commitcontract.ActionProposal) {
|
|
actor := identity.ActorID(ids.ID("creator-actor"))
|
|
principal := identity.PrincipalID(ids.ID("creator-principal"))
|
|
scope := authority.Scope{ID: authority.ScopeID(ids.ID("global")), Global: true, Label: "all"}
|
|
grant := authority.AuthorityGrant{ID: authority.GrantID(ids.ID("grant")), ActorID: actor, PrincipalID: principal, ScopeID: scope.ID, Class: authority.GrantClassCreator, Revision: 1, Active: true}
|
|
context := commitdomain.AuthorizationContext{Binding: identity.PrincipalBinding{ActorID: actor, PrincipalID: principal, Active: true}, Scope: scope, Grant: grant}
|
|
proposal := commitcontract.ActionProposal{IntentID: commitcontract.ActionIntentID(ids.ID("intent")), ActorID: actor, CapabilityID: commitcontract.CapabilityTestExecutor, Target: work.TaskTarget{TaskID: work.TaskID(ids.ID("task")), GoalID: work.GoalID(ids.ID("goal")), ScopeID: scope.ID, Revision: 1}, Operation: commitcontract.OperationTestIdempotentEffect}
|
|
return context, proposal
|
|
}
|