feat: [AH-983]: add unit tests (#3544)

* feat: [AH-983]: add unit tests
main
Tudor Macari 2025-03-13 22:51:50 +00:00 committed by Harness
parent 10a3e8bbc0
commit 6fb141f027
15 changed files with 1952 additions and 31 deletions

3
go.mod
View File

@ -67,7 +67,7 @@ require (
github.com/sercand/kuberesolver/v5 v5.1.1
github.com/sirupsen/logrus v1.9.3
github.com/slack-go/slack v0.14.0
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/swaggest/openapi-go v0.2.23
github.com/swaggest/swgui v1.8.1
github.com/swaggo/http-swagger v1.3.4
@ -158,6 +158,7 @@ require (
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.19.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect
go.opencensus.io v0.24.0 // indirect

3
go.sum
View File

@ -729,6 +729,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@ -742,6 +743,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=

View File

@ -22,7 +22,6 @@ import (
storagedriver "github.com/harness/gitness/registry/app/driver"
"github.com/harness/gitness/registry/app/pkg/filemanager"
"github.com/harness/gitness/registry/app/store"
registrywebhook "github.com/harness/gitness/registry/services/webhook"
"github.com/harness/gitness/store/database/dbtx"
)
@ -37,7 +36,7 @@ type APIController struct {
TagStore store.TagRepository
ManifestStore store.ManifestRepository
CleanupPolicyStore store.CleanupPolicyRepository
SpaceFinder refcache.SpaceFinder
SpaceFinder SpaceFinder
tx dbtx.Transactor
StorageDriver storagedriver.StorageDriver
URLProvider urlprovider.Provider
@ -47,7 +46,7 @@ type APIController struct {
WebhooksRepository store.WebhooksRepository
WebhooksExecutionRepository store.WebhooksExecutionRepository
RegistryMetadataHelper RegistryMetadataHelper
WebhookService registrywebhook.Service
WebhookService WebhookService
}
func NewAPIController(
@ -70,7 +69,7 @@ func NewAPIController(
webhooksRepository store.WebhooksRepository,
webhooksExecutionRepository store.WebhooksExecutionRepository,
registryMetadataHelper RegistryMetadataHelper,
webhookService registrywebhook.Service,
webhookService WebhookService,
) *APIController {
return &APIController{
fileManager: fileManager,

View File

@ -16,6 +16,7 @@ package metadata
import (
"context"
"fmt"
"net/http"
"strconv"
@ -65,7 +66,8 @@ func (c *APIController) GetWebhookExecution(
log.Ctx(ctx).Error().Msgf("invalid webhook execution identifier: %s, err: %v", string(r.WebhookExecutionId), err)
return api.GetWebhookExecution400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse(
*GetErrorResponse(http.StatusBadRequest, err.Error()),
*GetErrorResponse(http.StatusBadRequest,
fmt.Sprintf("invalid webhook execution identifier: %s, err: %v", string(r.WebhookExecutionId), err)),
),
}, err
}
@ -73,7 +75,7 @@ func (c *APIController) GetWebhookExecution(
w, err := c.WebhooksExecutionRepository.Find(ctx, webhookExecutionID)
if err != nil {
log.Ctx(ctx).Error().Msgf(getWebhookErrMsg, regInfo.RegistryRef, r.WebhookIdentifier, err)
return getWebhooksExecutionsInternalErrorResponse(err)
return getWebhooksExecutionsInternalErrorResponse(fmt.Errorf("failed to find webhook execution: %w", err))
}
webhookExecution, err := MapToWebhookExecutionResponseEntity(*w)
if err != nil {

View File

@ -0,0 +1,261 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
import (
"context"
"fmt"
"testing"
"time"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
gitnesstypes "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
//nolint:errcheck
func TestGetWebhookExecution_Success(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space,
regInfo.RegistryIdentifier, enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockWebhooksExecutionRepository.On("Find", ctx, int64(1)).Return(&gitnesstypes.WebhookExecutionCore{
ID: 1,
Created: time.Now().Unix(),
Duration: 100,
Error: "none",
Request: gitnesstypes.WebhookExecutionRequest{
Body: "{}", Headers: "headers", URL: "http://example.com",
},
Response: gitnesstypes.WebhookExecutionResponse{
Body: "{}", Headers: "headers", Status: "200 OK", StatusCode: 200,
},
RetriggerOf: nil,
Retriggerable: true,
WebhookID: 4,
Result: enum.WebhookExecutionResultSuccess,
TriggerType: enum.WebhookTriggerArtifactCreated}, nil)
r := api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
}
response, err := controller.GetWebhookExecution(ctx, r)
assert.NoError(t, err)
assert.NotNil(t, response)
assert.Equal(t, api.StatusSUCCESS, response.(api.GetWebhookExecution200JSONResponse).Status)
assert.Equal(t, int64(1), *response.(api.GetWebhookExecution200JSONResponse).Data.Id)
assert.Equal(t, "none", *response.(api.GetWebhookExecution200JSONResponse).Data.Error)
assert.Equal(t, "{}", *response.(api.GetWebhookExecution200JSONResponse).Data.Request.Body)
assert.Equal(t, "headers", *response.(api.GetWebhookExecution200JSONResponse).Data.Request.Headers)
assert.Equal(t, "http://example.com", *response.(api.GetWebhookExecution200JSONResponse).Data.Request.Url)
assert.Equal(t, "{}", *response.(api.GetWebhookExecution200JSONResponse).Data.Response.Body)
assert.Equal(t, "headers", *response.(api.GetWebhookExecution200JSONResponse).Data.Response.Headers)
assert.Equal(t, "200 OK", *response.(api.GetWebhookExecution200JSONResponse).Data.Response.Status)
assert.Equal(t, 200, *response.(api.GetWebhookExecution200JSONResponse).Data.Response.StatusCode)
assert.Equal(t, api.WebhookExecResultSUCCESS, *response.(api.GetWebhookExecution200JSONResponse).Data.Result)
assert.Equal(t, api.TriggerARTIFACTCREATION, *response.(api.GetWebhookExecution200JSONResponse).Data.TriggerType)
assert.Equal(t, api.StatusSUCCESS, response.(api.GetWebhookExecution200JSONResponse).Status)
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockWebhooksExecutionRepository.AssertExpectations(t)
}
//nolint:errcheck
func TestGetWebhookExecution_PermissionCheckFails(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView,
).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(false, nil)
r := api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
}
response, err := controller.GetWebhookExecution(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.GetWebhookExecution403JSONResponse{}, response)
assert.Contains(t, err.Error(), "not authorized")
assert.Equal(t, "not authorized", response.(api.GetWebhookExecution403JSONResponse).Message)
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
}
//nolint:errcheck
func TestGetWebhookExecution_InvalidExecutionIdentifier(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView,
).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
r := api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "invalid",
}
response, err := controller.GetWebhookExecution(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.GetWebhookExecution400JSONResponse{}, response)
assert.Contains(t, err.Error(), "strconv.ParseInt: parsing \"invalid\": invalid syntax")
assert.Equal(t,
"invalid webhook execution identifier: invalid, err: strconv.ParseInt: parsing \"invalid\": invalid syntax",
response.(api.GetWebhookExecution400JSONResponse).Message)
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
}
//nolint:errcheck
func TestGetWebhookExecution_FindExecutionError(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier,
enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockWebhooksExecutionRepository.On("Find", ctx, int64(1)).
Return(nil, fmt.Errorf("error"))
r := api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
}
response, err := controller.GetWebhookExecution(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.GetWebhookExecution500JSONResponse{}, response)
assert.Contains(t, err.Error(), "failed to find webhook execution: error")
assert.Equal(t, "failed to find webhook execution: error",
response.(api.GetWebhookExecution500JSONResponse).Message)
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockWebhooksExecutionRepository.AssertExpectations(t)
}

View File

@ -0,0 +1,60 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
import (
"context"
gitnesswebhook "github.com/harness/gitness/app/services/webhook"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
type SpaceFinder interface {
FindByRef(ctx context.Context, spaceRef string) (*types.SpaceCore, error)
FindByID(ctx context.Context, spaceID int64) (*types.SpaceCore, error)
}
type RegistryMetadataHelper interface {
GetPermissionChecks(
space *types.SpaceCore,
registryIdentifier string,
permission enum.Permission,
) []types.PermissionCheck
GetRegistryRequestBaseInfo(
ctx context.Context,
parentRef string,
regRef string,
) (*RegistryRequestBaseInfo, error)
getSecretSpaceID(ctx context.Context, secretSpacePath *string) (int, error)
MapToAPIWebhookTriggers(triggers []enum.WebhookTrigger) []api.Trigger
MapToInternalWebhookTriggers(
triggers []api.Trigger,
) []enum.WebhookTrigger
MapToWebhookCore(
ctx context.Context,
webhookRequest api.WebhookRequest,
regInfo *RegistryRequestBaseInfo,
) (*types.WebhookCore, error)
MapToWebhookResponseEntity(
ctx context.Context,
createdWebhook *types.WebhookCore,
) (*api.Webhook, error)
}
type WebhookService interface {
ReTriggerWebhookExecution(ctx context.Context, webhookExecutionID int64) (*gitnesswebhook.TriggerResult, error)
}

View File

@ -16,6 +16,7 @@ package metadata
import (
"context"
"fmt"
"net/http"
apiauth "github.com/harness/gitness/app/api/auth"
@ -66,17 +67,19 @@ func (c *APIController) ListWebhookExecutions(
reg, err := c.RegistryRepository.GetByParentIDAndName(ctx, space.ID, regInfo.RegistryIdentifier)
if err != nil {
log.Ctx(ctx).Error().Msgf(listWebhooksErrMsg, regInfo.RegistryRef, r.WebhookIdentifier, err)
return listWebhooksExecutionsInternalErrorResponse(err)
return listWebhooksExecutionsInternalErrorResponse(fmt.Errorf("failed to find registry: %w", err))
}
webhook, err := c.WebhooksRepository.GetByRegistryAndIdentifier(ctx, reg.ID, string(r.WebhookIdentifier))
if err != nil {
log.Ctx(ctx).Error().Msgf(listWebhooksErrMsg, regInfo.RegistryRef, r.WebhookIdentifier, err)
return listWebhooksExecutionsInternalErrorResponse(err)
return listWebhooksExecutionsInternalErrorResponse(
fmt.Errorf("failed to find webhook [%s] : %w", r.WebhookIdentifier, err),
)
}
we, err := c.WebhooksExecutionRepository.ListForWebhook(ctx, webhook.ID, limit, int(pageNumber), size)
if err != nil {
log.Ctx(ctx).Error().Msgf(listWebhooksErrMsg, regInfo.RegistryRef, r.WebhookIdentifier, err)
return listWebhooksExecutionsInternalErrorResponse(err)
return listWebhooksExecutionsInternalErrorResponse(fmt.Errorf("failed to list webhook executions: %w", err))
}
webhookExecutions, err := mapToAPIListWebhooksExecutions(we)
if err != nil {
@ -86,7 +89,7 @@ func (c *APIController) ListWebhookExecutions(
count, err := c.WebhooksExecutionRepository.CountForWebhook(ctx, webhook.ID)
if err != nil {
log.Ctx(ctx).Error().Msgf(listWebhooksErrMsg, regInfo.RegistryRef, r.WebhookIdentifier, err)
return listWebhooksExecutionsInternalErrorResponse(err)
return listWebhooksExecutionsInternalErrorResponse(fmt.Errorf("failed to get webhook executions count: %w", err))
}
pageCount := GetPageCount(count, limit)
currentPageSize := len(webhookExecutions)
@ -172,6 +175,7 @@ func mapTpAPIExecutionResult(result enum.WebhookExecutionResult) api.WebhookExec
//nolint:exhaustive
func mapTpAPITriggerType(trigger enum.WebhookTrigger) api.Trigger {
//nolint:exhaustive
switch trigger {
case enum.WebhookTriggerArtifactCreated:
return api.TriggerARTIFACTCREATION

View File

@ -0,0 +1,532 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
import (
"context"
"fmt"
"testing"
"time"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/types"
gitnesstypes "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
//nolint:lll
func TestListWebhookExecutions_Success(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockRegistryRepository.On("GetByParentIDAndName", ctx, int64(2), "reg").Return(&types.Registry{ID: 3}, nil)
mockWebhooksRepository.On("GetByRegistryAndIdentifier", ctx, int64(3), "webhook").Return(&gitnesstypes.WebhookCore{ID: 4}, nil)
mockWebhooksExecutionRepository.On("ListForWebhook", ctx, int64(4), 10, 1, 10).Return([]*gitnesstypes.WebhookExecutionCore{
{
ID: 1,
Created: time.Now().Unix(),
Duration: 100,
Error: "none",
Request: gitnesstypes.WebhookExecutionRequest{Body: "{}", Headers: "headers", URL: "http://example.com"},
Response: gitnesstypes.WebhookExecutionResponse{Body: "{}", Headers: "headers", Status: "200 OK", StatusCode: 200},
RetriggerOf: nil,
Retriggerable: true,
WebhookID: 4,
Result: enum.WebhookExecutionResultSuccess,
TriggerType: enum.WebhookTriggerArtifactCreated,
},
}, nil)
mockWebhooksExecutionRepository.On("CountForWebhook", ctx, int64(4)).Return(int64(1), nil)
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(1)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
listWebhookExecutions200JSONResponse, ok := response.(api.ListWebhookExecutions200JSONResponse)
if !ok {
t.Fatalf("expected api.ListWebhookExecutions200JSONResponse, got %T", response)
}
assert.NoError(t, err)
assert.NotNil(t, response)
assert.Equal(t, api.StatusSUCCESS, listWebhookExecutions200JSONResponse.Status)
assert.Len(t, listWebhookExecutions200JSONResponse.Data.Executions, 1)
assert.Equal(t, int64(1), *listWebhookExecutions200JSONResponse.Data.Executions[0].Id)
assert.Equal(t, "none", *listWebhookExecutions200JSONResponse.Data.Executions[0].Error)
assert.Equal(t, "{}", *listWebhookExecutions200JSONResponse.Data.Executions[0].Request.Body)
assert.Equal(t, "headers", *listWebhookExecutions200JSONResponse.Data.Executions[0].Request.Headers)
assert.Equal(t, "http://example.com", *listWebhookExecutions200JSONResponse.Data.Executions[0].Request.Url)
assert.Equal(t, "{}", *listWebhookExecutions200JSONResponse.Data.Executions[0].Response.Body)
assert.Equal(t, "headers", *listWebhookExecutions200JSONResponse.Data.Executions[0].Response.Headers)
assert.Equal(t, "200 OK", *listWebhookExecutions200JSONResponse.Data.Executions[0].Response.Status)
assert.Equal(t, 200, *listWebhookExecutions200JSONResponse.Data.Executions[0].Response.StatusCode)
assert.Equal(t, api.WebhookExecResultSUCCESS, *listWebhookExecutions200JSONResponse.Data.Executions[0].Result)
assert.Equal(t, api.TriggerARTIFACTCREATION, *listWebhookExecutions200JSONResponse.Data.Executions[0].TriggerType)
assert.Equal(t, int64(1), *listWebhookExecutions200JSONResponse.Data.ItemCount)
assert.Equal(t, 1, *listWebhookExecutions200JSONResponse.Data.PageSize)
assert.Equal(t, int64(1), *listWebhookExecutions200JSONResponse.Data.PageIndex)
assert.Equal(t, int64(1), *listWebhookExecutions200JSONResponse.Data.PageCount)
assert.Equal(t, api.StatusSUCCESS, listWebhookExecutions200JSONResponse.Status)
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
mockWebhooksRepository.AssertExpectations(t)
mockWebhooksExecutionRepository.AssertExpectations(t)
}
//nolint:lll
func TestListWebhookExecutions_GetRegistryRequestBaseInfoError(t *testing.T) {
ctx := context.Background()
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(nil, fmt.Errorf("error"))
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(11)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ListWebhookExecutions500JSONResponse{}, response)
assert.Contains(t, err.Error(), "error")
mockRegistryMetadataHelper.AssertExpectations(t)
}
//nolint:lll
func TestListWebhookExecutions_FindByRefError(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(nil, fmt.Errorf("error"))
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(11)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ListWebhookExecutions500JSONResponse{}, response)
assert.Contains(t, err.Error(), "error")
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
}
//nolint:lll
func TestListWebhookExecutions_CheckPermissionsFails(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(false, nil)
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(11)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ListWebhookExecutions403JSONResponse{}, response)
assert.Contains(t, err.Error(), "not authorized")
assert.Equal(t, "not authorized", response.(api.ListWebhookExecutions403JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
}
//nolint:lll
func TestListWebhookExecutions_FailedToDetRegistry(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockRegistryRepository.On("GetByParentIDAndName", ctx, int64(2), "reg").Return(nil, fmt.Errorf("error"))
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(1)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ListWebhookExecutions500JSONResponse{}, response)
assert.Contains(t, err.Error(), "failed to find registry: error")
assert.Equal(t, "failed to find registry: error", response.(api.ListWebhookExecutions500JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
}
//nolint:lll
func TestListWebhookExecutions_FailedToGetWebhook(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockRegistryRepository.On("GetByParentIDAndName", ctx, int64(2), "reg").Return(&types.Registry{ID: 3}, nil)
mockWebhooksRepository.On("GetByRegistryAndIdentifier", ctx, int64(3), "webhook").Return(nil, fmt.Errorf("error"))
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(1)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ListWebhookExecutions500JSONResponse{}, response)
assert.Contains(t, err.Error(), "failed to find webhook [webhook] : error")
assert.Equal(t, "failed to find webhook [webhook] : error", response.(api.ListWebhookExecutions500JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
mockWebhooksRepository.AssertExpectations(t)
}
//nolint:lll
func TestListWebhookExecutions_FailedToGetWebhookExecutions(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockRegistryRepository.On("GetByParentIDAndName", ctx, int64(2), "reg").Return(&types.Registry{ID: 3}, nil)
mockWebhooksRepository.On("GetByRegistryAndIdentifier", ctx, int64(3), "webhook").Return(&gitnesstypes.WebhookCore{ID: 4}, nil)
mockWebhooksExecutionRepository.On("ListForWebhook", ctx, int64(4), 10, 1, 10).Return(nil, fmt.Errorf("error"))
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(1)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ListWebhookExecutions500JSONResponse{}, response)
assert.Contains(t, err.Error(), "failed to list webhook executions: error")
assert.Equal(t, "failed to list webhook executions: error", response.(api.ListWebhookExecutions500JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
mockWebhooksRepository.AssertExpectations(t)
mockWebhooksExecutionRepository.AssertExpectations(t)
}
//nolint:lll
func TestListWebhookExecutions_FailedToGetWebhooksCount(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryView).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockRegistryRepository.On("GetByParentIDAndName", ctx, int64(2), "reg").Return(&types.Registry{ID: 3}, nil)
mockWebhooksRepository.On("GetByRegistryAndIdentifier", ctx, int64(3), "webhook").Return(&gitnesstypes.WebhookCore{ID: 4}, nil)
mockWebhooksExecutionRepository.On("ListForWebhook", ctx, int64(4), 10, 1, 10).Return([]*gitnesstypes.WebhookExecutionCore{
{
ID: 1,
Created: time.Now().Unix(),
Duration: 100,
Error: "none",
Request: gitnesstypes.WebhookExecutionRequest{Body: "{}", Headers: "headers", URL: "http://example.com"},
Response: gitnesstypes.WebhookExecutionResponse{Body: "{}", Headers: "headers", Status: "200 OK", StatusCode: 200},
RetriggerOf: nil,
Retriggerable: true,
WebhookID: 4,
Result: enum.WebhookExecutionResultSuccess,
TriggerType: enum.WebhookTriggerArtifactCreated,
},
}, nil)
mockWebhooksExecutionRepository.On("CountForWebhook", ctx, int64(4)).Return(nil, fmt.Errorf("error"))
pageSize := api.PageSize(10)
pageNumber := api.PageNumber(1)
r := api.ListWebhookExecutionsRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
Params: api.ListWebhookExecutionsParams{
Size: &pageSize,
Page: &pageNumber,
},
}
response, err := controller.ListWebhookExecutions(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ListWebhookExecutions500JSONResponse{}, response)
assert.Contains(t, err.Error(), "failed to get webhook executions count: error")
assert.Equal(t, "failed to get webhook executions count: error", response.(api.ListWebhookExecutions500JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
mockWebhooksRepository.AssertExpectations(t)
mockWebhooksExecutionRepository.AssertExpectations(t)
}
//nolint:lll
func TestMapToWebhookExecutionResponseEntity(t *testing.T) {
execution := gitnesstypes.WebhookExecutionCore{
Created: 1234567890,
Duration: 100,
ID: 1,
Error: "none",
Request: gitnesstypes.WebhookExecutionRequest{Body: "{}", Headers: "headers", URL: "http://example.com"},
Response: gitnesstypes.WebhookExecutionResponse{Body: "{}", Headers: "headers", Status: "200 OK", StatusCode: 200},
RetriggerOf: nil,
Retriggerable: true,
WebhookID: 4,
Result: enum.WebhookExecutionResultSuccess,
TriggerType: enum.WebhookTriggerArtifactCreated,
}
result := api.WebhookExecResultSUCCESS
triggerType := api.TriggerARTIFACTCREATION
expected := &api.WebhookExecution{
Created: &execution.Created,
Duration: &execution.Duration,
Id: &execution.ID,
Error: &execution.Error,
Request: &api.WebhookExecRequest{
Body: &execution.Request.Body,
Headers: &execution.Request.Headers,
Url: &execution.Request.URL,
},
Response: &api.WebhookExecResponse{
Body: &execution.Response.Body,
Headers: &execution.Response.Headers,
Status: &execution.Response.Status,
StatusCode: &execution.Response.StatusCode,
},
RetriggerOf: execution.RetriggerOf,
Retriggerable: &execution.Retriggerable,
WebhookId: &execution.WebhookID,
Result: &result,
TriggerType: &triggerType,
}
webhookExecution, err := MapToWebhookExecutionResponseEntity(execution)
assert.NoError(t, err)
assert.Equal(t, expected, webhookExecution)
}

View File

@ -0,0 +1,385 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
//nolint:gocritic
import (
"context"
"github.com/harness/gitness/app/auth"
gitnesswebhook "github.com/harness/gitness/app/services/webhook"
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/store"
"github.com/harness/gitness/registry/types"
gitnesstypes "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/mock"
)
type MockWebhooksRepository struct{ mock.Mock }
type MockRegistryMetadataHelper struct{ mock.Mock }
type MockWebhookService struct{ mock.Mock }
type MockAuthorizer struct{ mock.Mock }
type MockWebhooksExecutionRepository struct{ mock.Mock }
type MockSpaceFinder struct{ mock.Mock }
type MockRegistryRepository struct{ mock.Mock }
type MockSpacePathStore struct{ mock.Mock }
//nolint:errcheck
func (m *MockWebhookService) ReTriggerWebhookExecution(
ctx context.Context,
webhookExecutionID int64,
) (*gitnesswebhook.TriggerResult, error) {
args := m.Called(ctx, webhookExecutionID)
if args.Get(0) != nil {
return args.Get(0).(*gitnesswebhook.TriggerResult), args.Error(1)
}
return nil, args.Error(1)
}
//nolint:errcheck
func (m *MockRegistryMetadataHelper) GetPermissionChecks(
space *gitnesstypes.SpaceCore,
registryIdentifier string,
permission enum.Permission,
) []gitnesstypes.PermissionCheck {
args := m.Called(space, registryIdentifier, permission)
if args.Get(0) != nil {
return args.Get(0).([]gitnesstypes.PermissionCheck)
}
return nil
}
//nolint:errcheck
func (m *MockRegistryMetadataHelper) GetRegistryRequestBaseInfo(
ctx context.Context,
parentRef string,
regRef string,
) (*RegistryRequestBaseInfo, error) {
args := m.Called(ctx, parentRef, regRef)
if args.Get(0) != nil {
return args.Get(0).(*RegistryRequestBaseInfo), args.Error(1)
}
return nil, args.Error(1)
}
func (m *MockRegistryMetadataHelper) getSecretSpaceID(_ context.Context, _ *string) (int, error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryMetadataHelper) MapToAPIWebhookTriggers(
_ []enum.WebhookTrigger,
) []artifact.Trigger {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryMetadataHelper) MapToInternalWebhookTriggers(
_ []artifact.Trigger,
) []enum.WebhookTrigger {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryMetadataHelper) MapToWebhookCore(
_ context.Context,
_ artifact.WebhookRequest,
_ *RegistryRequestBaseInfo,
) (*gitnesstypes.WebhookCore, error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryMetadataHelper) MapToWebhookResponseEntity(
_ context.Context,
_ *gitnesstypes.WebhookCore,
) (*artifact.Webhook, error) {
// TODO implement me
panic("implement me")
}
func (m *MockAuthorizer) Check(
_ context.Context,
_ *auth.Session,
_ *gitnesstypes.Scope,
_ *gitnesstypes.Resource,
_ enum.Permission,
) (bool, error) {
// TODO implement me
panic("implement me")
}
//nolint:errcheck
func (m *MockAuthorizer) CheckAll(
ctx context.Context,
session *auth.Session,
permissionChecks ...gitnesstypes.PermissionCheck,
) (bool, error) {
args := m.Called(ctx, session, permissionChecks)
return args.Get(0).(bool), args.Error(1)
}
//nolint:errcheck
func (m *MockWebhooksExecutionRepository) Find(
ctx context.Context,
id int64,
) (*gitnesstypes.WebhookExecutionCore, error) {
args := m.Called(ctx, id)
if args.Get(0) != nil {
return args.Get(0).(*gitnesstypes.WebhookExecutionCore), args.Error(1)
}
return nil, args.Error(1)
}
func (m *MockWebhooksExecutionRepository) Create(_ context.Context, _ *gitnesstypes.WebhookExecutionCore) error {
// TODO implement me
panic("implement me")
}
//nolint:errcheck
func (m *MockWebhooksExecutionRepository) ListForWebhook(
ctx context.Context,
webhookID int64,
limit int,
page int,
size int,
) ([]*gitnesstypes.WebhookExecutionCore, error) {
args := m.Called(ctx, webhookID, limit, page, size)
if args.Get(0) != nil {
return args.Get(0).([]*gitnesstypes.WebhookExecutionCore), args.Error(1)
}
return nil, args.Error(1)
}
//nolint:errcheck
func (m *MockWebhooksExecutionRepository) CountForWebhook(ctx context.Context, webhookID int64) (int64, error) {
args := m.Called(ctx, webhookID)
if args.Get(1) == nil {
return args.Get(0).(int64), nil
}
return 0, args.Error(1)
}
func (m *MockWebhooksExecutionRepository) ListForTrigger(
_ context.Context,
_ string,
) ([]*gitnesstypes.WebhookExecutionCore, error) {
// TODO implement me
panic("implement me")
}
func (m *MockWebhooksRepository) Create(_ context.Context, _ *gitnesstypes.WebhookCore) error {
// TODO implement me
panic("implement me")
}
//nolint:errcheck
func (m *MockWebhooksRepository) GetByRegistryAndIdentifier(
ctx context.Context,
registryID int64,
webhookIdentifier string,
) (*gitnesstypes.WebhookCore, error) {
args := m.Called(ctx, registryID, webhookIdentifier)
if args.Get(0) != nil {
return args.Get(0).(*gitnesstypes.WebhookCore), args.Error(1)
}
return nil, args.Error(1)
}
func (m *MockWebhooksRepository) Find(_ context.Context, _ int64) (*gitnesstypes.WebhookCore, error) {
// TODO implement me
panic("implement me")
}
func (m *MockWebhooksRepository) ListByRegistry(
_ context.Context,
_ string,
_ string,
_ int,
_ int,
_ string,
_ int64,
) ([]*gitnesstypes.WebhookCore, error) {
// TODO implement me
panic("implement me")
}
func (m *MockWebhooksRepository) ListAllByRegistry(
_ context.Context,
_ []gitnesstypes.WebhookParentInfo,
) ([]*gitnesstypes.WebhookCore, error) {
// TODO implement me
panic("implement me")
}
func (m *MockWebhooksRepository) CountAllByRegistry(
_ context.Context, _ int64, _ string,
) (int64, error) {
// TODO implement me
panic("implement me")
}
func (m *MockWebhooksRepository) Update(_ context.Context, _ *gitnesstypes.WebhookCore) error {
// TODO implement me
panic("implement me")
}
func (m *MockWebhooksRepository) DeleteByRegistryAndIdentifier(
_ context.Context, _ int64, _ string,
) error {
// TODO implement me
panic("implement me")
}
func (m *MockWebhooksRepository) UpdateOptLock(
_ context.Context, _ *gitnesstypes.WebhookCore, _ func(hook *gitnesstypes.WebhookCore) error,
) (*gitnesstypes.WebhookCore, error) {
// TODO implement me
panic("implement me")
}
func (m *MockSpaceFinder) FindByID(_ context.Context, _ int64) (*gitnesstypes.SpaceCore, error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) Get(_ context.Context, _ int64) (repository *types.Registry, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) GetByIDIn(_ context.Context, _ []int64) (registries *[]types.Registry, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) GetByRootParentIDAndName(
_ context.Context, _ int64, _ string,
) (registry *types.Registry, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) Create(_ context.Context, _ *types.Registry) (id int64, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) Delete(_ context.Context, _ int64, _ string) (err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) Update(_ context.Context, _ *types.Registry) (err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) GetAll(
_ context.Context, _ int64, _ []string, _ string, _ string, _ int, _ int, _ string, _ string, _ bool,
) (repos *[]store.RegistryMetadata, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) CountAll(
_ context.Context, _ int64, _ []string, _ string, _ string,
) (count int64, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) FetchUpstreamProxyIDs(
_ context.Context,
_ []string,
_ int64,
) (ids []int64, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) FetchRegistriesIDByUpstreamProxyID(
_ context.Context, _ string, _ int64,
) (ids []int64, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) FetchUpstreamProxyKeys(_ context.Context, _ []int64) (repokeys []string, err error) {
// TODO implement me
panic("implement me")
}
func (m *MockRegistryRepository) Count(_ context.Context) (int64, error) {
// TODO implement me
panic("implement me")
}
func (m *MockSpacePathStore) InsertSegment(_ context.Context, _ *gitnesstypes.SpacePathSegment) error {
// TODO implement me
panic("implement me")
}
//nolint:errcheck
func (m *MockSpacePathStore) FindByPath(ctx context.Context, path string) (*gitnesstypes.SpacePath, error) {
args := m.Called(ctx, path)
if args.Get(0) != nil {
return args.Get(0).(*gitnesstypes.SpacePath), args.Error(1)
}
return nil, args.Error(1)
}
func (m *MockSpacePathStore) DeletePrimarySegment(_ context.Context, _ int64) error {
// TODO implement me
panic("implement me")
}
func (m *MockSpacePathStore) DeletePathsAndDescendandPaths(_ context.Context, _ int64) error {
// TODO implement me
panic("implement me")
}
//nolint:errcheck
func (m *MockSpaceFinder) FindByRef(ctx context.Context, ref string) (*gitnesstypes.SpaceCore, error) {
args := m.Called(ctx, ref)
if args.Get(0) != nil {
return args.Get(0).(*gitnesstypes.SpaceCore), args.Error(1)
}
return nil, args.Error(1)
}
//nolint:errcheck
func (m *MockRegistryRepository) GetByParentIDAndName(
ctx context.Context,
parentID int64,
name string,
) (*types.Registry, error) {
args := m.Called(ctx, parentID, name)
if args.Get(0) != nil {
return args.Get(0).(*types.Registry), args.Error(1)
}
return nil, args.Error(1)
}
//nolint:errcheck
func (m *MockSpacePathStore) FindPrimaryBySpaceID(ctx context.Context, spaceID int64) (*gitnesstypes.SpacePath, error) {
args := m.Called(ctx, spaceID)
if args.Get(0) != nil {
return args.Get(0).(*gitnesstypes.SpacePath), args.Error(1)
}
return nil, args.Error(1)
}

View File

@ -20,7 +20,6 @@ import (
"strconv"
"github.com/harness/gitness/app/paths"
"github.com/harness/gitness/app/services/refcache"
corestore "github.com/harness/gitness/app/store"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/pkg/commons"
@ -29,25 +28,29 @@ import (
"github.com/harness/gitness/types/enum"
)
type RegistryMetadataHelper struct {
var _ RegistryMetadataHelper = (*GitnessRegistryMetadataHelper)(nil)
var _ RegistryMetadataHelper = (*MockRegistryMetadataHelper)(nil)
type GitnessRegistryMetadataHelper struct {
spacePathStore corestore.SpacePathStore
spaceFinder refcache.SpaceFinder
spaceFinder SpaceFinder
registryRepository store.RegistryRepository
}
func NewRegistryMetadataHelper(
spacePathStore corestore.SpacePathStore,
spaceFinder refcache.SpaceFinder,
spaceFinder SpaceFinder,
registryRepository store.RegistryRepository,
) *RegistryMetadataHelper {
return &RegistryMetadataHelper{
) RegistryMetadataHelper {
gitnessRegistryMetadataHelper := GitnessRegistryMetadataHelper{
spacePathStore: spacePathStore,
spaceFinder: spaceFinder,
registryRepository: registryRepository,
}
return &gitnessRegistryMetadataHelper
}
func (r *RegistryMetadataHelper) getSecretSpaceID(ctx context.Context, secretSpacePath *string) (int, error) {
func (r *GitnessRegistryMetadataHelper) getSecretSpaceID(ctx context.Context, secretSpacePath *string) (int, error) {
if secretSpacePath == nil {
return -1, fmt.Errorf("secret space path is missing")
}
@ -61,7 +64,7 @@ func (r *RegistryMetadataHelper) getSecretSpaceID(ctx context.Context, secretSpa
// GetRegistryRequestBaseInfo returns the base info for the registry request
// One of the regRefParam or (parentRefParam + regIdentifierParam) should be provided.
func (r *RegistryMetadataHelper) GetRegistryRequestBaseInfo(
func (r *GitnessRegistryMetadataHelper) GetRegistryRequestBaseInfo(
ctx context.Context,
parentRef string,
regRef string,
@ -116,7 +119,7 @@ func (r *RegistryMetadataHelper) GetRegistryRequestBaseInfo(
return baseInfo, nil
}
func (r *RegistryMetadataHelper) GetPermissionChecks(
func (r *GitnessRegistryMetadataHelper) GetPermissionChecks(
space *types.SpaceCore,
registryIdentifier string,
permission enum.Permission,
@ -131,7 +134,7 @@ func (r *RegistryMetadataHelper) GetPermissionChecks(
return permissionChecks
}
func (r *RegistryMetadataHelper) MapToWebhookCore(
func (r *GitnessRegistryMetadataHelper) MapToWebhookCore(
ctx context.Context,
webhookRequest api.WebhookRequest,
regInfo *RegistryRequestBaseInfo,
@ -182,7 +185,7 @@ func mapToDTOHeaders(extraHeaders *[]api.ExtraHeader) []types.ExtraHeader {
return headers
}
func (r *RegistryMetadataHelper) MapToWebhookResponseEntity(
func (r *GitnessRegistryMetadataHelper) MapToWebhookResponseEntity(
ctx context.Context,
createdWebhook *types.WebhookCore,
) (*api.Webhook, error) {
@ -241,7 +244,7 @@ func (r *RegistryMetadataHelper) MapToWebhookResponseEntity(
return webhookResponseEntity, nil
}
func (r *RegistryMetadataHelper) MapToInternalWebhookTriggers(
func (r *GitnessRegistryMetadataHelper) MapToInternalWebhookTriggers(
triggers []api.Trigger,
) []enum.WebhookTrigger {
var webhookTriggers = make([]enum.WebhookTrigger, 0)
@ -258,7 +261,9 @@ func (r *RegistryMetadataHelper) MapToInternalWebhookTriggers(
return webhookTriggers
}
func (r *RegistryMetadataHelper) MapToAPIExecutionResult(result enum.WebhookExecutionResult) api.WebhookExecResult {
func (r *GitnessRegistryMetadataHelper) MapToAPIExecutionResult(
result enum.WebhookExecutionResult,
) api.WebhookExecResult {
switch result {
case enum.WebhookExecutionResultSuccess:
return api.WebhookExecResultSUCCESS
@ -271,7 +276,7 @@ func (r *RegistryMetadataHelper) MapToAPIExecutionResult(result enum.WebhookExec
return ""
}
func (r *RegistryMetadataHelper) MapToAPIWebhookTriggers(triggers []enum.WebhookTrigger) []api.Trigger {
func (r *GitnessRegistryMetadataHelper) MapToAPIWebhookTriggers(triggers []enum.WebhookTrigger) []api.Trigger {
var webhookTriggers = make([]api.Trigger, 0)
for _, trigger := range triggers {
//nolint:exhaustive
@ -287,7 +292,7 @@ func (r *RegistryMetadataHelper) MapToAPIWebhookTriggers(triggers []enum.Webhook
return webhookTriggers
}
func (r *RegistryMetadataHelper) MapToAPIExtraHeaders(headers []types.ExtraHeader) []api.ExtraHeader {
func (r *GitnessRegistryMetadataHelper) MapToAPIExtraHeaders(headers []types.ExtraHeader) []api.ExtraHeader {
apiHeaders := make([]api.ExtraHeader, 0)
for _, h := range headers {
apiHeaders = append(apiHeaders, api.ExtraHeader{Key: h.Key, Value: h.Value})

View File

@ -0,0 +1,381 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
import (
"context"
"fmt"
"strconv"
"testing"
"time"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/types"
gitnesstypes "github.com/harness/gitness/types"
gitnessenum "github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
)
//nolint:lll
func TestGetRegistryRequestBaseInfo(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
mockSpaceFinder.On("FindByRef", ctx, "root").Return(&gitnesstypes.SpaceCore{ID: 1}, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(&gitnesstypes.SpaceCore{ID: 2}, nil)
mockRegistryRepository.On("GetByParentIDAndName", ctx, int64(2), "reg").Return(&types.Registry{ID: 3, Type: api.RegistryTypeVIRTUAL}, nil)
baseInfo, err := helper.GetRegistryRequestBaseInfo(ctx, "root/parent", "reg")
assert.NoError(t, err)
assert.NotNil(t, baseInfo)
assert.Equal(t, int64(1), baseInfo.rootIdentifierID)
assert.Equal(t, int64(2), baseInfo.parentID)
assert.Equal(t, int64(3), baseInfo.RegistryID)
assert.Equal(t, api.RegistryTypeVIRTUAL, baseInfo.RegistryType)
}
func TestGetRegistryRequestBaseInfo_EmptyParentRef(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
helper := &GitnessRegistryMetadataHelper{
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
_, err := helper.GetRegistryRequestBaseInfo(ctx, "", "reg")
assert.Error(t, err)
assert.Equal(t, "parent reference is required", err.Error())
}
//nolint:lll
func TestGetRegistryRequestBaseInfo_InvalidParentRef(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
helper := &GitnessRegistryMetadataHelper{
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
_, err := helper.GetRegistryRequestBaseInfo(ctx, "/", "reg")
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid parent reference")
}
func TestGetRegistryRequestBaseInfo_RootSpaceNotFound(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
helper := &GitnessRegistryMetadataHelper{
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
mockSpaceFinder.On("FindByRef", ctx, "root").Return(nil, fmt.Errorf("not found"))
_, err := helper.GetRegistryRequestBaseInfo(ctx, "root/parent", "reg")
assert.Error(t, err)
assert.Contains(t, err.Error(), "root space not found")
}
func TestGetRegistryRequestBaseInfo_ParentSpaceNotFound(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
helper := &GitnessRegistryMetadataHelper{
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
mockSpaceFinder.On("FindByRef", ctx, "root").Return(&gitnesstypes.SpaceCore{ID: 1}, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(nil, fmt.Errorf("not found"))
_, err := helper.GetRegistryRequestBaseInfo(ctx, "root/parent", "reg")
assert.Error(t, err)
assert.Contains(t, err.Error(), "parent space not found")
}
func TestGetRegistryRequestBaseInfo_RegistryNotFound(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
helper := &GitnessRegistryMetadataHelper{
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
mockSpaceFinder.On("FindByRef", ctx, "root").Return(&gitnesstypes.SpaceCore{ID: 1}, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(&gitnesstypes.SpaceCore{ID: 2}, nil)
mockRegistryRepository.On("GetByParentIDAndName", ctx, int64(2), "reg").Return(nil, fmt.Errorf("not found"))
_, err := helper.GetRegistryRequestBaseInfo(ctx, "root/parent", "reg")
assert.Error(t, err)
assert.Contains(t, err.Error(), "registry not found")
}
func TestGetPermissionChecks(t *testing.T) {
helper := &GitnessRegistryMetadataHelper{}
space := &gitnesstypes.SpaceCore{Path: "space/path"}
permissionChecks := helper.GetPermissionChecks(space, "registry", gitnessenum.PermissionRegistryEdit)
assert.Len(t, permissionChecks, 1)
assert.Equal(t, "space/path", permissionChecks[0].Scope.SpacePath)
assert.Equal(t, "registry", permissionChecks[0].Resource.Identifier)
assert.Equal(t, gitnessenum.PermissionRegistryEdit, permissionChecks[0].Permission)
}
//nolint:goconst
func TestMapToWebhook(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
key := "key"
value := "value"
extraHeaders := []api.ExtraHeader{{Key: key, Value: value}}
description := "Test webhook"
webhookRequest := api.WebhookRequest{
Identifier: "webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: &[]api.Trigger{api.TriggerARTIFACTCREATION, api.TriggerARTIFACTCREATION, api.TriggerARTIFACTDELETION},
Description: &description,
ExtraHeaders: &extraHeaders,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
}
webhook, err := helper.MapToWebhookCore(ctx, webhookRequest, regInfo)
assert.NoError(t, err)
assert.NotNil(t, webhook)
assert.Equal(t, "webhook", webhook.Identifier)
assert.Equal(t, "http://example.com", webhook.URL)
assert.Equal(t, true, webhook.Enabled)
assert.Equal(t, false, webhook.Insecure)
assert.Len(t, webhook.Triggers, 2)
assert.Contains(t, webhook.Triggers, gitnessenum.WebhookTriggerArtifactCreated)
assert.Contains(t, webhook.Triggers, gitnessenum.WebhookTriggerArtifactDeleted)
assert.Equal(t, "Test webhook", webhook.Description)
assert.Equal(t, extraHeaders[0].Key, key)
assert.Equal(t, extraHeaders[0].Value, value)
}
//nolint:lll
func TestMapToWebhook_WithSecretSpacePath(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
secretSpacePath := "secret/path"
webhookRequest := api.WebhookRequest{
Identifier: "webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: &[]api.Trigger{api.TriggerARTIFACTCREATION},
SecretSpacePath: &secretSpacePath,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
}
mockSpacePathStore.On("FindByPath", ctx, "secret/path").Return(&gitnesstypes.SpacePath{Value: "secret/path", SpaceID: 2}, nil)
webhook, err := helper.MapToWebhookCore(ctx, webhookRequest, regInfo)
assert.NoError(t, err)
assert.NotNil(t, webhook)
assert.Equal(t, "webhook", webhook.Identifier)
assert.Equal(t, "http://example.com", webhook.URL)
assert.Equal(t, true, webhook.Enabled)
assert.Equal(t, false, webhook.Insecure)
assert.Len(t, webhook.Triggers, 1)
assert.Equal(t, gitnessenum.WebhookTriggerArtifactCreated, webhook.Triggers[0])
assert.Equal(t, 2, webhook.SecretSpaceID)
}
func TestMapToWebhook_WithInexistentSecretSpacePath(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
secretSpacePath := "secret/path"
webhookRequest := api.WebhookRequest{
Identifier: "webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: &[]api.Trigger{api.TriggerARTIFACTCREATION},
SecretSpacePath: &secretSpacePath,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
}
mockSpacePathStore.On("FindByPath", ctx, "secret/path").Return(nil, fmt.Errorf("not found"))
webhook, err := helper.MapToWebhookCore(ctx, webhookRequest, regInfo)
assert.Nil(t, webhook)
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to get Space Path: not found")
}
func TestMapToWebhookResponseEntity(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
createdAt := time.Now().Unix()
updatedAt := time.Now().Unix()
description := "Test webhook"
secretIdentifier := "secret-id"
extraHeaders := []gitnesstypes.ExtraHeader{{Key: "key", Value: "value"}}
latestExecutionResult := gitnessenum.WebhookExecutionResultSuccess
createdWebhook := gitnesstypes.WebhookCore{
Type: gitnessenum.WebhookTypeInternal,
Identifier: "webhook",
DisplayName: "webhook",
URL: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: []gitnessenum.WebhookTrigger{gitnessenum.WebhookTriggerArtifactCreated},
Created: createdAt,
Updated: updatedAt,
Description: description,
SecretIdentifier: secretIdentifier,
SecretSpaceID: 1,
ExtraHeaders: extraHeaders,
LatestExecutionResult: &latestExecutionResult,
}
mockSpacePathStore.On("FindPrimaryBySpaceID", ctx, int64(1)).Return(&gitnesstypes.SpacePath{Value: "secret/path"}, nil)
webhookResponseEntity, err := helper.MapToWebhookResponseEntity(ctx, &createdWebhook)
assert.NoError(t, err)
assert.NotNil(t, webhookResponseEntity)
assert.Equal(t, "webhook", webhookResponseEntity.Identifier)
assert.Equal(t, "webhook", webhookResponseEntity.Name)
assert.Equal(t, "http://example.com", webhookResponseEntity.Url)
assert.Equal(t, true, webhookResponseEntity.Enabled)
assert.Equal(t, false, webhookResponseEntity.Insecure)
assert.Len(t, *webhookResponseEntity.Triggers, 1)
assert.Equal(t, api.TriggerARTIFACTCREATION, (*webhookResponseEntity.Triggers)[0])
assert.Equal(t, &description, webhookResponseEntity.Description)
assert.Equal(t, &createdWebhook.Version, webhookResponseEntity.Version)
assert.True(t, *webhookResponseEntity.Internal)
assert.Equal(t, &createdWebhook.CreatedBy, webhookResponseEntity.CreatedBy)
assert.Equal(t, strconv.FormatInt(createdAt, 10), *webhookResponseEntity.CreatedAt)
assert.Equal(t, strconv.FormatInt(updatedAt, 10), *webhookResponseEntity.ModifiedAt)
assert.Equal(t, api.WebhookExecResultSUCCESS, *webhookResponseEntity.LatestExecutionResult)
assert.Equal(t, "key", extraHeaders[0].Key)
assert.Equal(t, "value", extraHeaders[0].Value)
assert.Equal(t, "secret-id", *webhookResponseEntity.SecretIdentifier)
assert.Equal(t, "secret/path", *webhookResponseEntity.SecretSpacePath)
assert.Equal(t, 1, *webhookResponseEntity.SecretSpaceId)
}
//nolint:lll
func TestMapToWebhookResponseEntity_FindPrimaryBySpaceIDError(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
createdAt := time.Now().Unix()
updatedAt := time.Now().Unix()
description := "Test webhook"
secretIdentifier := "secret-id"
extraHeaders := []gitnesstypes.ExtraHeader{{Key: "key", Value: "value"}}
latestExecutionResult := gitnessenum.WebhookExecutionResultSuccess
createdWebhook := gitnesstypes.WebhookCore{
Identifier: "webhook",
DisplayName: "webhook",
URL: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: []gitnessenum.WebhookTrigger{gitnessenum.WebhookTriggerArtifactCreated},
Created: createdAt,
Updated: updatedAt,
Description: description,
SecretIdentifier: secretIdentifier,
SecretSpaceID: 1,
ExtraHeaders: extraHeaders,
LatestExecutionResult: &latestExecutionResult,
}
mockSpacePathStore.On("FindPrimaryBySpaceID", ctx, int64(1)).Return(nil, fmt.Errorf("error finding primary by space ID"))
webhookResponseEntity, err := helper.MapToWebhookResponseEntity(ctx, &createdWebhook)
assert.Error(t, err)
assert.Nil(t, webhookResponseEntity)
assert.Contains(t, err.Error(), "failed to get secret space path: error finding primary by space ID")
}
func TestMapToInternalWebhookTriggers(t *testing.T) {
helper := &GitnessRegistryMetadataHelper{}
apiTriggers := []api.Trigger{
api.TriggerARTIFACTCREATION,
api.TriggerARTIFACTMODIFICATION,
api.TriggerARTIFACTDELETION,
}
expectedInternalTriggers := []gitnessenum.WebhookTrigger{
gitnessenum.WebhookTriggerArtifactCreated,
gitnessenum.WebhookTriggerArtifactUpdated,
gitnessenum.WebhookTriggerArtifactDeleted,
}
internalTriggers := helper.MapToInternalWebhookTriggers(apiTriggers)
assert.Equal(t, expectedInternalTriggers, internalTriggers)
}
func TestMapToAPIWebhookTriggers(t *testing.T) {
helper := &GitnessRegistryMetadataHelper{}
internalTriggers := []gitnessenum.WebhookTrigger{
gitnessenum.WebhookTriggerArtifactCreated,
gitnessenum.WebhookTriggerArtifactUpdated,
gitnessenum.WebhookTriggerArtifactDeleted,
}
expectedAPITriggers := []api.Trigger{
api.TriggerARTIFACTCREATION,
api.TriggerARTIFACTMODIFICATION,
api.TriggerARTIFACTDELETION,
}
apiTriggers := helper.MapToAPIWebhookTriggers(internalTriggers)
assert.Equal(t, expectedAPITriggers, apiTriggers)
}

View File

@ -16,6 +16,7 @@ package metadata
import (
"context"
"fmt"
"net/http"
"strconv"
@ -63,13 +64,14 @@ func (c *APIController) ReTriggerWebhookExecution(
log.Ctx(ctx).Error().Msgf("invalid webhook execution identifier: %s, err: %v", string(r.WebhookExecutionId), err)
return api.ReTriggerWebhookExecution400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse(
*GetErrorResponse(http.StatusBadRequest, err.Error()),
*GetErrorResponse(http.StatusBadRequest,
fmt.Sprintf("invalid webhook execution identifier: %s, err: %v", string(r.WebhookExecutionId), err)),
),
}, err
}
result, err := c.WebhookService.WebhookExecutor.RetriggerWebhookExecution(ctx, webhookExecutionID)
result, err := c.WebhookService.ReTriggerWebhookExecution(ctx, webhookExecutionID)
if err != nil {
return getReTriggerWebhooksExecutionsInternalErrorResponse(err)
return getReTriggerWebhooksExecutionsInternalErrorResponse(fmt.Errorf("failed to re-trigger execution: %w", err))
}
webhookExecution, err := MapToWebhookExecutionResponseEntity(*result.Execution)
if err != nil {

View File

@ -0,0 +1,279 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
import (
"context"
"fmt"
"testing"
"time"
gitnesswebhook "github.com/harness/gitness/app/services/webhook"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
gitnesstypes "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
//nolint:lll
func TestReTriggerWebhookExecution_Success(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
mockMockWebhookService := new(MockWebhookService)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
WebhookService: mockMockWebhookService,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
latestExecutionResult := enum.WebhookExecutionResultSuccess
mockMockWebhookService.On("ReTriggerWebhookExecution", ctx, int64(1)).Return(&gitnesswebhook.TriggerResult{
Execution: &gitnesstypes.WebhookExecutionCore{
ID: 1,
Created: time.Now().Unix(),
Duration: 100,
Error: "none",
Request: gitnesstypes.WebhookExecutionRequest{Body: "{}", Headers: "headers", URL: "http://example.com"},
Response: gitnesstypes.WebhookExecutionResponse{Body: "{}", Headers: "headers", Status: "200 OK", StatusCode: 200},
RetriggerOf: nil,
Retriggerable: true,
WebhookID: 4,
Result: enum.WebhookExecutionResultSuccess,
TriggerType: enum.WebhookTriggerArtifactCreated},
Webhook: &gitnesstypes.WebhookCore{
Identifier: "webhook",
DisplayName: "webhook",
URL: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: []enum.WebhookTrigger{enum.WebhookTriggerArtifactCreated},
Created: time.Now().Unix(),
Updated: time.Now().Unix(),
Description: "Test webhook",
SecretSpaceID: 1,
ExtraHeaders: []gitnesstypes.ExtraHeader{{Key: "key", Value: "value"}},
LatestExecutionResult: &latestExecutionResult,
},
TriggerType: enum.WebhookTriggerArtifactCreated,
}, nil)
r := api.ReTriggerWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
}
response, err := controller.ReTriggerWebhookExecution(ctx, r)
reTriggerWebhookExecution200JSONResponse, ok := response.(api.ReTriggerWebhookExecution200JSONResponse)
if !ok {
t.Fatalf("expected api.ReTriggerWebhookExecution200JSONResponse, got %T", response)
}
assert.NoError(t, err)
assert.NotNil(t, response)
assert.Equal(t, api.StatusSUCCESS, reTriggerWebhookExecution200JSONResponse.Status)
assert.Equal(t, int64(1), *reTriggerWebhookExecution200JSONResponse.Data.Id)
assert.Equal(t, "none", *reTriggerWebhookExecution200JSONResponse.Data.Error)
assert.Equal(t, "{}", *reTriggerWebhookExecution200JSONResponse.Data.Request.Body)
assert.Equal(t, "headers", *reTriggerWebhookExecution200JSONResponse.Data.Request.Headers)
assert.Equal(t, "http://example.com", *reTriggerWebhookExecution200JSONResponse.Data.Request.Url)
assert.Equal(t, "{}", *reTriggerWebhookExecution200JSONResponse.Data.Response.Body)
assert.Equal(t, "headers", *reTriggerWebhookExecution200JSONResponse.Data.Response.Headers)
assert.Equal(t, "200 OK", *reTriggerWebhookExecution200JSONResponse.Data.Response.Status)
assert.Equal(t, 200, *reTriggerWebhookExecution200JSONResponse.Data.Response.StatusCode)
assert.Equal(t, api.WebhookExecResultSUCCESS, *reTriggerWebhookExecution200JSONResponse.Data.Result)
assert.Equal(t, api.TriggerARTIFACTCREATION, *reTriggerWebhookExecution200JSONResponse.Data.TriggerType)
assert.Equal(t, api.StatusSUCCESS, reTriggerWebhookExecution200JSONResponse.Status)
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockWebhooksExecutionRepository.AssertExpectations(t)
mockMockWebhookService.AssertExpectations(t)
}
//nolint:lll
func TestReTriggerWebhookExecution_PermissionCheckFails(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
mockMockWebhookService := new(MockWebhookService)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
WebhookService: mockMockWebhookService,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(false, nil)
r := api.ReTriggerWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
}
response, err := controller.ReTriggerWebhookExecution(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ReTriggerWebhookExecution403JSONResponse{}, response)
assert.Contains(t, err.Error(), "not authorized")
assert.Equal(t, "not authorized", response.(api.ReTriggerWebhookExecution403JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
}
//nolint:lll
func TestReTriggerWebhookExecution_InvalidExecutionIdentifier(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
mockMockWebhookService := new(MockWebhookService)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
WebhookService: mockMockWebhookService,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
r := api.ReTriggerWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "invalid",
}
response, err := controller.ReTriggerWebhookExecution(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ReTriggerWebhookExecution400JSONResponse{}, response)
assert.Contains(t, err.Error(), "strconv.ParseInt: parsing \"invalid\": invalid syntax")
assert.Equal(t, "invalid webhook execution identifier: invalid, err: strconv.ParseInt: parsing \"invalid\": invalid syntax",
response.(api.ReTriggerWebhookExecution400JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
}
//nolint:lll
func TestReTriggerWebhookExecution_ReTriggerExecutionError(t *testing.T) {
ctx := context.Background()
mockSpaceFinder := new(MockSpaceFinder)
mockRegistryRepository := new(MockRegistryRepository)
mockWebhooksRepository := new(MockWebhooksRepository)
mockWebhooksExecutionRepository := new(MockWebhooksExecutionRepository)
mockAuthorizer := new(MockAuthorizer)
mockRegistryMetadataHelper := new(MockRegistryMetadataHelper)
mockMockWebhookService := new(MockWebhookService)
controller := &APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
WebhookService: mockMockWebhookService,
}
regInfo := &RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &gitnesstypes.SpaceCore{ID: 2}
var permissionChecks []gitnesstypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", ctx, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", ctx, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", ctx, mock.Anything, permissionChecks).Return(true, nil)
mockMockWebhookService.On("ReTriggerWebhookExecution", ctx, int64(1)).Return(nil, fmt.Errorf("error"))
r := api.ReTriggerWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
}
response, err := controller.ReTriggerWebhookExecution(ctx, r)
assert.Error(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ReTriggerWebhookExecution500JSONResponse{}, response)
assert.Contains(t, err.Error(), "failed to re-trigger execution: error")
assert.Equal(t, "failed to re-trigger execution: error", response.(api.ReTriggerWebhookExecution500JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
}

View File

@ -99,8 +99,8 @@ func NewAPIHandler(
artifactStore,
webhooksRepository,
webhooksExecutionRepository,
*registryMetadataHelper,
webhookService,
registryMetadataHelper,
&webhookService,
)
handler := artifact.NewStrictHandler(apiController, []artifact.StrictMiddlewareFunc{})

View File

@ -107,3 +107,10 @@ func NewService(
return service, nil
}
func (s *Service) ReTriggerWebhookExecution(
ctx context.Context,
webhookExecutionID int64,
) (*gitnesswebhook.TriggerResult, error) {
return s.WebhookExecutor.RetriggerWebhookExecution(ctx, webhookExecutionID)
}