mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 04:57:33 +00:00
feat: actions v2 api GA (#10364)
# Which Problems Are Solved The Actions v2beta API is not yet promoted to GA. # How the Problems Are Solved Promote Actions v2Beta API to Actions v2 API. # Additional Changes None # Additional Context None
This commit is contained in:
File diff suppressed because it is too large
Load Diff
565
internal/api/grpc/action/v2/integration_test/execution_test.go
Normal file
565
internal/api/grpc/action/v2/integration_test/execution_test.go
Normal file
@@ -0,0 +1,565 @@
|
||||
//go:build integration
|
||||
|
||||
package action_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/action/v2"
|
||||
)
|
||||
|
||||
func TestServer_SetExecution_Request(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
req *action.SetExecutionRequest
|
||||
wantSetDate bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_All{All: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no condition, error",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "method, not existing",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2.NotExistingService/List",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "method, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2.SessionService/ListSessions",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
{
|
||||
name: "service, not existing",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Service{
|
||||
Service: "NotExistingService",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "service, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Service{
|
||||
Service: "zitadel.session.v2.SessionService",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
{
|
||||
name: "all, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_All{
|
||||
All: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// We want to have the same response no matter how often we call the function
|
||||
creationDate := time.Now().UTC()
|
||||
got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req)
|
||||
setDate := time.Now().UTC()
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
|
||||
assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got)
|
||||
|
||||
// cleanup to not impact other requests
|
||||
instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertSetExecutionResponse(t *testing.T, creationDate, setDate time.Time, expectedSetDate bool, actualResp *action.SetExecutionResponse) {
|
||||
if expectedSetDate {
|
||||
if !setDate.IsZero() {
|
||||
assert.WithinRange(t, actualResp.GetSetDate().AsTime(), creationDate, setDate)
|
||||
} else {
|
||||
assert.WithinRange(t, actualResp.GetSetDate().AsTime(), creationDate, time.Now().UTC())
|
||||
}
|
||||
} else {
|
||||
assert.Nil(t, actualResp.SetDate)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_SetExecution_Response(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
req *action.SetExecutionRequest
|
||||
wantSetDate bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{
|
||||
Condition: &action.ResponseExecution_All{All: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no condition, error",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "method, not existing",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{
|
||||
Condition: &action.ResponseExecution_Method{
|
||||
Method: "/zitadel.session.v2.NotExistingService/List",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "method, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{
|
||||
Condition: &action.ResponseExecution_Method{
|
||||
Method: "/zitadel.session.v2.SessionService/ListSessions",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
{
|
||||
name: "service, not existing",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{
|
||||
Condition: &action.ResponseExecution_Service{
|
||||
Service: "NotExistingService",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "service, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{
|
||||
Condition: &action.ResponseExecution_Service{
|
||||
Service: "zitadel.session.v2.SessionService",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
{
|
||||
name: "all, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{
|
||||
Condition: &action.ResponseExecution_All{
|
||||
All: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
creationDate := time.Now().UTC()
|
||||
got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req)
|
||||
setDate := time.Now().UTC()
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got)
|
||||
|
||||
// cleanup to not impact other requests
|
||||
instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_SetExecution_Event(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
req *action.SetExecutionRequest
|
||||
wantSetDate bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{
|
||||
Condition: &action.EventExecution_All{
|
||||
All: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no condition, error",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "event, not existing",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{
|
||||
Condition: &action.EventExecution_Event{
|
||||
Event: "user.human.notexisting",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "event, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{
|
||||
Condition: &action.EventExecution_Event{
|
||||
Event: "user.human.added",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
{
|
||||
name: "group, not existing",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{
|
||||
Condition: &action.EventExecution_Group{
|
||||
Group: "user.notexisting",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "group, level 1, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{
|
||||
Condition: &action.EventExecution_Group{
|
||||
Group: "user",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
{
|
||||
name: "group, level 2, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{
|
||||
Condition: &action.EventExecution_Group{
|
||||
Group: "user.human",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
{
|
||||
name: "all, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Event{
|
||||
Event: &action.EventExecution{
|
||||
Condition: &action.EventExecution_All{
|
||||
All: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
creationDate := time.Now().UTC()
|
||||
got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req)
|
||||
setDate := time.Now().UTC()
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got)
|
||||
|
||||
// cleanup to not impact other requests
|
||||
instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_SetExecution_Function(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
req *action.SetExecutionRequest
|
||||
wantSetDate bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{
|
||||
Condition: &action.ResponseExecution_All{All: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no condition, error",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Response{
|
||||
Response: &action.ResponseExecution{},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "function, not existing",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Function{
|
||||
Function: &action.FunctionExecution{Name: "xxx"},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "function, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Function{
|
||||
Function: &action.FunctionExecution{Name: "presamlresponse"},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
wantSetDate: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
creationDate := time.Now().UTC()
|
||||
got, err := instance.Client.ActionV2.SetExecution(tt.ctx, tt.req)
|
||||
setDate := time.Now().UTC()
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got)
|
||||
|
||||
// cleanup to not impact other requests
|
||||
instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition())
|
||||
})
|
||||
}
|
||||
}
|
784
internal/api/grpc/action/v2/integration_test/query_test.go
Normal file
784
internal/api/grpc/action/v2/integration_test/query_test.go
Normal file
@@ -0,0 +1,784 @@
|
||||
//go:build integration
|
||||
|
||||
package action_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/action/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/filter/v2"
|
||||
)
|
||||
|
||||
func TestServer_GetTarget(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
dep func(context.Context, *action.GetTargetRequest, *action.GetTargetResponse) error
|
||||
req *action.GetTargetRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *action.GetTargetResponse
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
args: args{
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.GetTargetRequest{},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "not found",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.GetTargetRequest{Id: "notexisting"},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "get, ok",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
||||
name := gofakeit.Name()
|
||||
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false)
|
||||
request.Id = resp.GetId()
|
||||
response.Target.Id = resp.GetId()
|
||||
response.Target.Name = name
|
||||
response.Target.CreationDate = resp.GetCreationDate()
|
||||
response.Target.ChangeDate = resp.GetCreationDate()
|
||||
response.Target.SigningKey = resp.GetSigningKey()
|
||||
return nil
|
||||
},
|
||||
req: &action.GetTargetRequest{},
|
||||
},
|
||||
want: &action.GetTargetResponse{
|
||||
Target: &action.Target{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get, async, ok",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
||||
name := gofakeit.Name()
|
||||
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeAsync, false)
|
||||
request.Id = resp.GetId()
|
||||
response.Target.Id = resp.GetId()
|
||||
response.Target.Name = name
|
||||
response.Target.CreationDate = resp.GetCreationDate()
|
||||
response.Target.ChangeDate = resp.GetCreationDate()
|
||||
response.Target.SigningKey = resp.GetSigningKey()
|
||||
return nil
|
||||
},
|
||||
req: &action.GetTargetRequest{},
|
||||
},
|
||||
want: &action.GetTargetResponse{
|
||||
Target: &action.Target{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestAsync{
|
||||
RestAsync: &action.RESTAsync{},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get, webhook interruptOnError, ok",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
||||
name := gofakeit.Name()
|
||||
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, true)
|
||||
request.Id = resp.GetId()
|
||||
response.Target.Id = resp.GetId()
|
||||
response.Target.Name = name
|
||||
response.Target.CreationDate = resp.GetCreationDate()
|
||||
response.Target.ChangeDate = resp.GetCreationDate()
|
||||
response.Target.SigningKey = resp.GetSigningKey()
|
||||
return nil
|
||||
},
|
||||
req: &action.GetTargetRequest{},
|
||||
},
|
||||
want: &action.GetTargetResponse{
|
||||
Target: &action.Target{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{
|
||||
InterruptOnError: true,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get, call, ok",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
||||
name := gofakeit.Name()
|
||||
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeCall, false)
|
||||
request.Id = resp.GetId()
|
||||
response.Target.Id = resp.GetId()
|
||||
response.Target.Name = name
|
||||
response.Target.CreationDate = resp.GetCreationDate()
|
||||
response.Target.ChangeDate = resp.GetCreationDate()
|
||||
response.Target.SigningKey = resp.GetSigningKey()
|
||||
return nil
|
||||
},
|
||||
req: &action.GetTargetRequest{},
|
||||
},
|
||||
want: &action.GetTargetResponse{
|
||||
Target: &action.Target{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestCall{
|
||||
RestCall: &action.RESTCall{
|
||||
InterruptOnError: false,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get, call interruptOnError, ok",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
||||
name := gofakeit.Name()
|
||||
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeCall, true)
|
||||
request.Id = resp.GetId()
|
||||
response.Target.Id = resp.GetId()
|
||||
response.Target.Name = name
|
||||
response.Target.CreationDate = resp.GetCreationDate()
|
||||
response.Target.ChangeDate = resp.GetCreationDate()
|
||||
response.Target.SigningKey = resp.GetSigningKey()
|
||||
return nil
|
||||
},
|
||||
req: &action.GetTargetRequest{},
|
||||
},
|
||||
want: &action.GetTargetResponse{
|
||||
Target: &action.Target{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestCall{
|
||||
RestCall: &action.RESTCall{
|
||||
InterruptOnError: true,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.dep != nil {
|
||||
err := tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, 2*time.Minute)
|
||||
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
got, err := instance.Client.ActionV2.GetTarget(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
assert.Error(ttt, err, "Error: "+err.Error())
|
||||
return
|
||||
}
|
||||
assert.NoError(ttt, err)
|
||||
assert.EqualExportedValues(ttt, tt.want, got)
|
||||
}, retryDuration, tick, "timeout waiting for expected target Executions")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_ListTargets(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
dep func(context.Context, *action.ListTargetsRequest, *action.ListTargetsResponse)
|
||||
req *action.ListTargetsRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *action.ListTargetsResponse
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
args: args{
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.ListTargetsRequest{},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "list, not found",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.ListTargetsRequest{
|
||||
Filters: []*action.TargetSearchFilter{
|
||||
{Filter: &action.TargetSearchFilter_InTargetIdsFilter{
|
||||
InTargetIdsFilter: &action.InTargetIDsFilter{
|
||||
TargetIds: []string{"notfound"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &action.ListTargetsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 0,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Targets: []*action.Target{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list single id",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) {
|
||||
name := gofakeit.Name()
|
||||
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false)
|
||||
request.Filters[0].Filter = &action.TargetSearchFilter_InTargetIdsFilter{
|
||||
InTargetIdsFilter: &action.InTargetIDsFilter{
|
||||
TargetIds: []string{resp.GetId()},
|
||||
},
|
||||
}
|
||||
|
||||
response.Targets[0].Id = resp.GetId()
|
||||
response.Targets[0].Name = name
|
||||
response.Targets[0].CreationDate = resp.GetCreationDate()
|
||||
response.Targets[0].ChangeDate = resp.GetCreationDate()
|
||||
response.Targets[0].SigningKey = resp.GetSigningKey()
|
||||
},
|
||||
req: &action.ListTargetsRequest{
|
||||
Filters: []*action.TargetSearchFilter{{}},
|
||||
},
|
||||
},
|
||||
want: &action.ListTargetsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 1,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Targets: []*action.Target{
|
||||
{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{
|
||||
InterruptOnError: false,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "list single name",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) {
|
||||
name := gofakeit.Name()
|
||||
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false)
|
||||
request.Filters[0].Filter = &action.TargetSearchFilter_TargetNameFilter{
|
||||
TargetNameFilter: &action.TargetNameFilter{
|
||||
TargetName: name,
|
||||
},
|
||||
}
|
||||
|
||||
response.Targets[0].Id = resp.GetId()
|
||||
response.Targets[0].Name = name
|
||||
response.Targets[0].CreationDate = resp.GetCreationDate()
|
||||
response.Targets[0].ChangeDate = resp.GetCreationDate()
|
||||
response.Targets[0].SigningKey = resp.GetSigningKey()
|
||||
},
|
||||
req: &action.ListTargetsRequest{
|
||||
Filters: []*action.TargetSearchFilter{{}},
|
||||
},
|
||||
},
|
||||
want: &action.ListTargetsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 1,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Targets: []*action.Target{
|
||||
{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{
|
||||
InterruptOnError: false,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list multiple id",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) {
|
||||
name1 := gofakeit.Name()
|
||||
name2 := gofakeit.Name()
|
||||
name3 := gofakeit.Name()
|
||||
resp1 := instance.CreateTarget(ctx, t, name1, "https://example.com", domain.TargetTypeWebhook, false)
|
||||
resp2 := instance.CreateTarget(ctx, t, name2, "https://example.com", domain.TargetTypeCall, true)
|
||||
resp3 := instance.CreateTarget(ctx, t, name3, "https://example.com", domain.TargetTypeAsync, false)
|
||||
request.Filters[0].Filter = &action.TargetSearchFilter_InTargetIdsFilter{
|
||||
InTargetIdsFilter: &action.InTargetIDsFilter{
|
||||
TargetIds: []string{resp1.GetId(), resp2.GetId(), resp3.GetId()},
|
||||
},
|
||||
}
|
||||
|
||||
response.Targets[2].Id = resp1.GetId()
|
||||
response.Targets[2].Name = name1
|
||||
response.Targets[2].CreationDate = resp1.GetCreationDate()
|
||||
response.Targets[2].ChangeDate = resp1.GetCreationDate()
|
||||
response.Targets[2].SigningKey = resp1.GetSigningKey()
|
||||
|
||||
response.Targets[1].Id = resp2.GetId()
|
||||
response.Targets[1].Name = name2
|
||||
response.Targets[1].CreationDate = resp2.GetCreationDate()
|
||||
response.Targets[1].ChangeDate = resp2.GetCreationDate()
|
||||
response.Targets[1].SigningKey = resp2.GetSigningKey()
|
||||
|
||||
response.Targets[0].Id = resp3.GetId()
|
||||
response.Targets[0].Name = name3
|
||||
response.Targets[0].CreationDate = resp3.GetCreationDate()
|
||||
response.Targets[0].ChangeDate = resp3.GetCreationDate()
|
||||
response.Targets[0].SigningKey = resp3.GetSigningKey()
|
||||
},
|
||||
req: &action.ListTargetsRequest{
|
||||
Filters: []*action.TargetSearchFilter{{}},
|
||||
},
|
||||
},
|
||||
want: &action.ListTargetsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 3,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Targets: []*action.Target{
|
||||
{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestAsync{
|
||||
RestAsync: &action.RESTAsync{},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestCall{
|
||||
RestCall: &action.RESTCall{
|
||||
InterruptOnError: true,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
{
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.Target_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{
|
||||
InterruptOnError: false,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(5 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.dep != nil {
|
||||
tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
||||
}
|
||||
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, time.Minute)
|
||||
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
got, listErr := instance.Client.ActionV2.ListTargets(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(ttt, listErr, "Error: "+listErr.Error())
|
||||
return
|
||||
}
|
||||
require.NoError(ttt, listErr)
|
||||
|
||||
// always first check length, otherwise its failed anyway
|
||||
if assert.Len(ttt, got.Targets, len(tt.want.Targets)) {
|
||||
for i := range tt.want.Targets {
|
||||
assert.EqualExportedValues(ttt, tt.want.Targets[i], got.Targets[i])
|
||||
}
|
||||
}
|
||||
assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination)
|
||||
}, retryDuration, tick, "timeout waiting for expected execution Executions")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertPaginationResponse(t *assert.CollectT, expected *filter.PaginationResponse, actual *filter.PaginationResponse) {
|
||||
assert.Equal(t, expected.AppliedLimit, actual.AppliedLimit)
|
||||
assert.Equal(t, expected.TotalResult, actual.TotalResult)
|
||||
}
|
||||
|
||||
func TestServer_ListExecutions(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false)
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
dep func(context.Context, *action.ListExecutionsRequest, *action.ListExecutionsResponse)
|
||||
req *action.ListExecutionsRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *action.ListExecutionsResponse
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
args: args{
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.ListExecutionsRequest{},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "list request single condition",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
||||
cond := request.Filters[0].GetInConditionsFilter().GetConditions()[0]
|
||||
resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()})
|
||||
|
||||
// Set expected response with used values for SetExecution
|
||||
response.Executions[0].CreationDate = resp.GetSetDate()
|
||||
response.Executions[0].ChangeDate = resp.GetSetDate()
|
||||
response.Executions[0].Condition = cond
|
||||
},
|
||||
req: &action.ListExecutionsRequest{
|
||||
Filters: []*action.ExecutionSearchFilter{{
|
||||
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
||||
InConditionsFilter: &action.InConditionsFilter{
|
||||
Conditions: []*action.Condition{{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2.SessionService/GetSession",
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
want: &action.ListExecutionsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 1,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Executions: []*action.Execution{
|
||||
{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2.SessionService/GetSession",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: []string{targetResp.GetId()},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list request single target",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
||||
target := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false)
|
||||
// add target as Filter to the request
|
||||
request.Filters[0] = &action.ExecutionSearchFilter{
|
||||
Filter: &action.ExecutionSearchFilter_TargetFilter{
|
||||
TargetFilter: &action.TargetFilter{
|
||||
TargetId: target.GetId(),
|
||||
},
|
||||
},
|
||||
}
|
||||
cond := &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.management.v1.ManagementService/UpdateAction",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
resp := instance.SetExecution(ctx, t, cond, []string{target.GetId()})
|
||||
|
||||
response.Executions[0].CreationDate = resp.GetSetDate()
|
||||
response.Executions[0].ChangeDate = resp.GetSetDate()
|
||||
response.Executions[0].Condition = cond
|
||||
response.Executions[0].Targets = []string{target.GetId()}
|
||||
},
|
||||
req: &action.ListExecutionsRequest{
|
||||
Filters: []*action.ExecutionSearchFilter{{}},
|
||||
},
|
||||
},
|
||||
want: &action.ListExecutionsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 1,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Executions: []*action.Execution{
|
||||
{
|
||||
Condition: &action.Condition{},
|
||||
Targets: []string{""},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list multiple conditions",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
||||
|
||||
request.Filters[0] = &action.ExecutionSearchFilter{
|
||||
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
||||
InConditionsFilter: &action.InConditionsFilter{
|
||||
Conditions: []*action.Condition{
|
||||
{ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2.SessionService/GetSession",
|
||||
},
|
||||
},
|
||||
}},
|
||||
{ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2.SessionService/CreateSession",
|
||||
},
|
||||
},
|
||||
}},
|
||||
{ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2.SessionService/SetSession",
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cond1 := request.Filters[0].GetInConditionsFilter().GetConditions()[0]
|
||||
resp1 := instance.SetExecution(ctx, t, cond1, []string{targetResp.GetId()})
|
||||
response.Executions[2] = &action.Execution{
|
||||
CreationDate: resp1.GetSetDate(),
|
||||
ChangeDate: resp1.GetSetDate(),
|
||||
Condition: cond1,
|
||||
Targets: []string{targetResp.GetId()},
|
||||
}
|
||||
|
||||
cond2 := request.Filters[0].GetInConditionsFilter().GetConditions()[1]
|
||||
resp2 := instance.SetExecution(ctx, t, cond2, []string{targetResp.GetId()})
|
||||
response.Executions[1] = &action.Execution{
|
||||
CreationDate: resp2.GetSetDate(),
|
||||
ChangeDate: resp2.GetSetDate(),
|
||||
Condition: cond2,
|
||||
Targets: []string{targetResp.GetId()},
|
||||
}
|
||||
|
||||
cond3 := request.Filters[0].GetInConditionsFilter().GetConditions()[2]
|
||||
resp3 := instance.SetExecution(ctx, t, cond3, []string{targetResp.GetId()})
|
||||
response.Executions[0] = &action.Execution{
|
||||
CreationDate: resp3.GetSetDate(),
|
||||
ChangeDate: resp3.GetSetDate(),
|
||||
Condition: cond3,
|
||||
Targets: []string{targetResp.GetId()},
|
||||
}
|
||||
},
|
||||
req: &action.ListExecutionsRequest{
|
||||
Filters: []*action.ExecutionSearchFilter{
|
||||
{},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &action.ListExecutionsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 3,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Executions: []*action.Execution{
|
||||
{}, {}, {},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list multiple conditions all types",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
||||
conditions := request.Filters[0].GetInConditionsFilter().GetConditions()
|
||||
for i, cond := range conditions {
|
||||
resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()})
|
||||
response.Executions[(len(conditions)-1)-i] = &action.Execution{
|
||||
CreationDate: resp.GetSetDate(),
|
||||
ChangeDate: resp.GetSetDate(),
|
||||
Condition: cond,
|
||||
Targets: []string{targetResp.GetId()},
|
||||
}
|
||||
}
|
||||
},
|
||||
req: &action.ListExecutionsRequest{
|
||||
Filters: []*action.ExecutionSearchFilter{{
|
||||
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
||||
InConditionsFilter: &action.InConditionsFilter{
|
||||
Conditions: []*action.Condition{
|
||||
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
||||
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
||||
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}},
|
||||
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
||||
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
||||
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}},
|
||||
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: "user.added"}}}},
|
||||
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: "user"}}}},
|
||||
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}},
|
||||
{ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: "presamlresponse"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
want: &action.ListExecutionsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 10,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Executions: []*action.Execution{
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list multiple conditions all types, sort id",
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
||||
conditions := request.Filters[0].GetInConditionsFilter().GetConditions()
|
||||
for i, cond := range conditions {
|
||||
resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()})
|
||||
response.Executions[i] = &action.Execution{
|
||||
CreationDate: resp.GetSetDate(),
|
||||
ChangeDate: resp.GetSetDate(),
|
||||
Condition: cond,
|
||||
Targets: []string{targetResp.GetId()},
|
||||
}
|
||||
}
|
||||
},
|
||||
req: &action.ListExecutionsRequest{
|
||||
SortingColumn: gu.Ptr(action.ExecutionFieldName_EXECUTION_FIELD_NAME_ID),
|
||||
Filters: []*action.ExecutionSearchFilter{{
|
||||
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
||||
InConditionsFilter: &action.InConditionsFilter{
|
||||
Conditions: []*action.Condition{
|
||||
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
||||
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
||||
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}},
|
||||
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
||||
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
||||
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}},
|
||||
{ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: "presamlresponse"}}},
|
||||
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: "user.added"}}}},
|
||||
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: "user"}}}},
|
||||
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
want: &action.ListExecutionsResponse{
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: 10,
|
||||
AppliedLimit: 100,
|
||||
},
|
||||
Executions: []*action.Execution{
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.dep != nil {
|
||||
tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
||||
}
|
||||
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, time.Minute)
|
||||
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
got, listErr := instance.Client.ActionV2.ListExecutions(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(ttt, listErr, "Error: "+listErr.Error())
|
||||
return
|
||||
}
|
||||
require.NoError(ttt, listErr)
|
||||
// always first check length, otherwise its failed anyway
|
||||
if assert.Len(ttt, got.Executions, len(tt.want.Executions)) {
|
||||
assert.EqualExportedValues(ttt, got.Executions, tt.want.Executions)
|
||||
}
|
||||
assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination)
|
||||
}, retryDuration, tick, "timeout waiting for expected execution Executions")
|
||||
})
|
||||
}
|
||||
}
|
23
internal/api/grpc/action/v2/integration_test/server_test.go
Normal file
23
internal/api/grpc/action/v2/integration_test/server_test.go
Normal file
@@ -0,0 +1,23 @@
|
||||
//go:build integration
|
||||
|
||||
package action_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
CTX context.Context
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(func() int {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer cancel()
|
||||
CTX = ctx
|
||||
return m.Run()
|
||||
}())
|
||||
}
|
549
internal/api/grpc/action/v2/integration_test/target_test.go
Normal file
549
internal/api/grpc/action/v2/integration_test/target_test.go
Normal file
@@ -0,0 +1,549 @@
|
||||
//go:build integration
|
||||
|
||||
package action_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/action/v2"
|
||||
)
|
||||
|
||||
func TestServer_CreateTarget(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
type want struct {
|
||||
id bool
|
||||
creationDate bool
|
||||
signingKey bool
|
||||
}
|
||||
alreadyExistingTargetName := gofakeit.AppName()
|
||||
instance.CreateTarget(isolatedIAMOwnerCTX, t, alreadyExistingTargetName, "https://example.com", domain.TargetTypeAsync, false)
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
req *action.CreateTargetRequest
|
||||
want
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty name",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: "",
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty type",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
TargetType: nil,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty webhook url",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
TargetType: &action.CreateTargetRequest_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty request response url",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
TargetType: &action.CreateTargetRequest_RestCall{
|
||||
RestCall: &action.RESTCall{},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty timeout",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.CreateTargetRequest_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{},
|
||||
},
|
||||
Timeout: nil,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "async, already existing, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: alreadyExistingTargetName,
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.CreateTargetRequest_RestAsync{
|
||||
RestAsync: &action.RESTAsync{},
|
||||
},
|
||||
Timeout: durationpb.New(10 * time.Second),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "async, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.CreateTargetRequest_RestAsync{
|
||||
RestAsync: &action.RESTAsync{},
|
||||
},
|
||||
Timeout: durationpb.New(10 * time.Second),
|
||||
},
|
||||
want: want{
|
||||
id: true,
|
||||
creationDate: true,
|
||||
signingKey: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhook, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.CreateTargetRequest_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{
|
||||
InterruptOnError: false,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(10 * time.Second),
|
||||
},
|
||||
want: want{
|
||||
id: true,
|
||||
creationDate: true,
|
||||
signingKey: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhook, interrupt on error, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.CreateTargetRequest_RestWebhook{
|
||||
RestWebhook: &action.RESTWebhook{
|
||||
InterruptOnError: true,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(10 * time.Second),
|
||||
},
|
||||
want: want{
|
||||
id: true,
|
||||
creationDate: true,
|
||||
signingKey: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "call, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.CreateTargetRequest_RestCall{
|
||||
RestCall: &action.RESTCall{
|
||||
InterruptOnError: false,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(10 * time.Second),
|
||||
},
|
||||
want: want{
|
||||
id: true,
|
||||
creationDate: true,
|
||||
signingKey: true,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "call, interruptOnError, ok",
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.CreateTargetRequest{
|
||||
Name: gofakeit.Name(),
|
||||
Endpoint: "https://example.com",
|
||||
TargetType: &action.CreateTargetRequest_RestCall{
|
||||
RestCall: &action.RESTCall{
|
||||
InterruptOnError: true,
|
||||
},
|
||||
},
|
||||
Timeout: durationpb.New(10 * time.Second),
|
||||
},
|
||||
want: want{
|
||||
id: true,
|
||||
creationDate: true,
|
||||
signingKey: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
creationDate := time.Now().UTC()
|
||||
got, err := instance.Client.ActionV2.CreateTarget(tt.ctx, tt.req)
|
||||
changeDate := time.Now().UTC()
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
assertCreateTargetResponse(t, creationDate, changeDate, tt.want.creationDate, tt.want.id, tt.want.signingKey, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertCreateTargetResponse(t *testing.T, creationDate, changeDate time.Time, expectedCreationDate, expectedID, expectedSigningKey bool, actualResp *action.CreateTargetResponse) {
|
||||
if expectedCreationDate {
|
||||
if !changeDate.IsZero() {
|
||||
assert.WithinRange(t, actualResp.GetCreationDate().AsTime(), creationDate, changeDate)
|
||||
} else {
|
||||
assert.WithinRange(t, actualResp.GetCreationDate().AsTime(), creationDate, time.Now().UTC())
|
||||
}
|
||||
} else {
|
||||
assert.Nil(t, actualResp.CreationDate)
|
||||
}
|
||||
|
||||
if expectedID {
|
||||
assert.NotEmpty(t, actualResp.GetId())
|
||||
} else {
|
||||
assert.Nil(t, actualResp.Id)
|
||||
}
|
||||
|
||||
if expectedSigningKey {
|
||||
assert.NotEmpty(t, actualResp.GetSigningKey())
|
||||
} else {
|
||||
assert.Nil(t, actualResp.SigningKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_UpdateTarget(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *action.UpdateTargetRequest
|
||||
}
|
||||
type want struct {
|
||||
change bool
|
||||
changeDate bool
|
||||
signingKey bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
prepare func(request *action.UpdateTargetRequest)
|
||||
args args
|
||||
want want
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.UpdateTargetRequest{
|
||||
Name: gu.Ptr(gofakeit.Name()),
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "not existing",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
request.Id = "notexisting"
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
Name: gu.Ptr(gofakeit.Name()),
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no change, ok",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
Endpoint: gu.Ptr("https://example.com"),
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
change: false,
|
||||
changeDate: true,
|
||||
signingKey: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change name, ok",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
Name: gu.Ptr(gofakeit.Name()),
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
change: true,
|
||||
changeDate: true,
|
||||
signingKey: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "regenerate signingkey, ok",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
ExpirationSigningKey: durationpb.New(0 * time.Second),
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
change: true,
|
||||
changeDate: true,
|
||||
signingKey: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change type, ok",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
TargetType: &action.UpdateTargetRequest_RestCall{
|
||||
RestCall: &action.RESTCall{
|
||||
InterruptOnError: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
change: true,
|
||||
changeDate: true,
|
||||
signingKey: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change url, ok",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
Endpoint: gu.Ptr("https://example.com/hooks/new"),
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
change: true,
|
||||
changeDate: true,
|
||||
signingKey: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change timeout, ok",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
Timeout: durationpb.New(20 * time.Second),
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
change: true,
|
||||
changeDate: true,
|
||||
signingKey: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change type async, ok",
|
||||
prepare: func(request *action.UpdateTargetRequest) {
|
||||
targetID := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeAsync, false).GetId()
|
||||
request.Id = targetID
|
||||
},
|
||||
args: args{
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &action.UpdateTargetRequest{
|
||||
TargetType: &action.UpdateTargetRequest_RestAsync{
|
||||
RestAsync: &action.RESTAsync{},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: want{
|
||||
change: true,
|
||||
changeDate: true,
|
||||
signingKey: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
creationDate := time.Now().UTC()
|
||||
tt.prepare(tt.args.req)
|
||||
|
||||
got, err := instance.Client.ActionV2.UpdateTarget(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
changeDate := time.Time{}
|
||||
if tt.want.change {
|
||||
changeDate = time.Now().UTC()
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
assertUpdateTargetResponse(t, creationDate, changeDate, tt.want.changeDate, tt.want.signingKey, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertUpdateTargetResponse(t *testing.T, creationDate, changeDate time.Time, expectedChangeDate, expectedSigningKey bool, actualResp *action.UpdateTargetResponse) {
|
||||
if expectedChangeDate {
|
||||
if !changeDate.IsZero() {
|
||||
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, changeDate)
|
||||
} else {
|
||||
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, time.Now().UTC())
|
||||
}
|
||||
} else {
|
||||
assert.Nil(t, actualResp.ChangeDate)
|
||||
}
|
||||
|
||||
if expectedSigningKey {
|
||||
assert.NotEmpty(t, actualResp.GetSigningKey())
|
||||
} else {
|
||||
assert.Nil(t, actualResp.SigningKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_DeleteTarget(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
prepare func(request *action.DeleteTargetRequest) (time.Time, time.Time)
|
||||
req *action.DeleteTargetRequest
|
||||
wantDeletionDate bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing permission",
|
||||
ctx: instance.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &action.DeleteTargetRequest{
|
||||
Id: "notexisting",
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty id",
|
||||
ctx: iamOwnerCtx,
|
||||
req: &action.DeleteTargetRequest{
|
||||
Id: "",
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "delete target, not existing",
|
||||
ctx: iamOwnerCtx,
|
||||
req: &action.DeleteTargetRequest{
|
||||
Id: "notexisting",
|
||||
},
|
||||
wantDeletionDate: false,
|
||||
},
|
||||
{
|
||||
name: "delete target",
|
||||
ctx: iamOwnerCtx,
|
||||
prepare: func(request *action.DeleteTargetRequest) (time.Time, time.Time) {
|
||||
creationDate := time.Now().UTC()
|
||||
targetID := instance.CreateTarget(iamOwnerCtx, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
return creationDate, time.Time{}
|
||||
},
|
||||
req: &action.DeleteTargetRequest{},
|
||||
wantDeletionDate: true,
|
||||
},
|
||||
{
|
||||
name: "delete target, already removed",
|
||||
ctx: iamOwnerCtx,
|
||||
prepare: func(request *action.DeleteTargetRequest) (time.Time, time.Time) {
|
||||
creationDate := time.Now().UTC()
|
||||
targetID := instance.CreateTarget(iamOwnerCtx, t, "", "https://example.com", domain.TargetTypeWebhook, false).GetId()
|
||||
request.Id = targetID
|
||||
instance.DeleteTarget(iamOwnerCtx, t, targetID)
|
||||
return creationDate, time.Now().UTC()
|
||||
},
|
||||
req: &action.DeleteTargetRequest{},
|
||||
wantDeletionDate: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var creationDate, deletionDate time.Time
|
||||
if tt.prepare != nil {
|
||||
creationDate, deletionDate = tt.prepare(tt.req)
|
||||
}
|
||||
got, err := instance.Client.ActionV2.DeleteTarget(tt.ctx, tt.req)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
assertDeleteTargetResponse(t, creationDate, deletionDate, tt.wantDeletionDate, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertDeleteTargetResponse(t *testing.T, creationDate, deletionDate time.Time, expectedDeletionDate bool, actualResp *action.DeleteTargetResponse) {
|
||||
if expectedDeletionDate {
|
||||
if !deletionDate.IsZero() {
|
||||
assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), creationDate, deletionDate)
|
||||
} else {
|
||||
assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), creationDate, time.Now().UTC())
|
||||
}
|
||||
} else {
|
||||
assert.Nil(t, actualResp.DeletionDate)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user