fix: [AH-771]: gitness unit test refactoring (#3589)

* fix merge conflicts
* fix merge conflicts
* fix review comment
* fix review comment
* fix review comment
* fix: [AH-771]: gitness unit test refactoring
* fix: [AH-771]: resolved review comments
* fix: [AH-771]: resolved review comments
* fix: [AH-771] Registry test refactoring and improvements

- Refactored registry metadata test implementations
- Improved code organization and readability
- Fixed line length issues in test files
- Removed unused fields from request.go
- Added proper license headers
- Fixed linting issues in mock files
- Simplified test setup and assertions
- Updated wire generation for cmd package
- Added nolint:exhaustive directive for package type switch

fix: [AH-771] Registry test refactoring and improvements

- Refactored registry metadata test implementations
- Improved code organization and readability
- Fixed line length issues in test files
- Removed unused fields from request.go
- Added proper license headers
- Fixed linting issues in mock files
- Simplifi
This commit is contained in:
Manjunatha EN 2025-04-22 14:49:24 +00:00 committed by Harness
parent 0d478a34cc
commit a73113f8e6
71 changed files with 9873 additions and 1941 deletions

View File

@ -199,6 +199,10 @@ linters:
- goheader # checks is file header matches to pattern
- misspell # [useless] finds commonly misspelled English words in comments
run:
skip-dirs:
- registry/app/api/controller/mocks
issues:
# Maximum count of issues with the same text.
# Set to 0 to disable.

View File

@ -37,23 +37,8 @@ const MediaTypeImageConfig = "application/vnd.docker.container.image.v1+json"
var _ api.StrictServerInterface = (*APIController)(nil)
type RegistryRequestBaseInfo struct {
RootIdentifier string
rootIdentifierID int64
RegistryRef string
RegistryIdentifier string
RegistryID int64
ParentRef string
parentID int64
RegistryType api.RegistryType
PackageType api.PackageType
}
type RegistryRequestInfo struct {
RegistryRequestBaseInfo
*types.RegistryRequestBaseInfo
packageTypes []string
sortByField string
sortByOrder string
@ -82,7 +67,7 @@ type RegistryRequestParams struct {
}
type ArtifactFilesRequestInfo struct {
RegistryRequestBaseInfo
*types.RegistryRequestBaseInfo
sortByField string
sortByOrder string
offset int
@ -138,7 +123,7 @@ func (c *APIController) GetRegistryRequestInfo(
}
return &RegistryRequestInfo{
RegistryRequestBaseInfo: *baseInfo,
RegistryRequestBaseInfo: baseInfo,
packageTypes: packageTypes,
sortByField: sortByField,
sortByOrder: sortByOrder,
@ -415,7 +400,7 @@ func (c *APIController) GetArtifactFilesRequestInfo(
}
return &ArtifactFilesRequestInfo{
RegistryRequestBaseInfo: *baseInfo,
RegistryRequestBaseInfo: baseInfo,
sortByField: sortByField,
sortByOrder: sortByOrder,
offset: offset,

View File

@ -16,13 +16,14 @@ package metadata
import (
"github.com/harness/gitness/app/auth/authz"
"github.com/harness/gitness/app/services/refcache"
urlprovider "github.com/harness/gitness/app/url"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/registry/app/api/interfaces"
storagedriver "github.com/harness/gitness/registry/app/driver"
registryevents "github.com/harness/gitness/registry/app/events"
"github.com/harness/gitness/registry/app/pkg/filemanager"
"github.com/harness/gitness/registry/app/store"
"github.com/harness/gitness/registry/services/webhook"
"github.com/harness/gitness/store/database/dbtx"
)
@ -37,7 +38,7 @@ type APIController struct {
TagStore store.TagRepository
ManifestStore store.ManifestRepository
CleanupPolicyStore store.CleanupPolicyRepository
SpaceFinder SpaceFinder
SpaceFinder interfaces.SpaceFinder
tx dbtx.Transactor
StorageDriver storagedriver.StorageDriver
URLProvider urlprovider.Provider
@ -46,8 +47,8 @@ type APIController struct {
ArtifactStore store.ArtifactRepository
WebhooksRepository store.WebhooksRepository
WebhooksExecutionRepository store.WebhooksExecutionRepository
RegistryMetadataHelper RegistryMetadataHelper
WebhookService WebhookService
RegistryMetadataHelper interfaces.RegistryMetadataHelper
WebhookService webhook.ServiceInterface
ArtifactEventReporter registryevents.Reporter
DownloadStatRepository store.DownloadStatRepository
}
@ -63,7 +64,7 @@ func NewAPIController(
cleanupPolicyStore store.CleanupPolicyRepository,
imageStore store.ImageRepository,
driver storagedriver.StorageDriver,
spaceFinder refcache.SpaceFinder,
spaceFinder interfaces.SpaceFinder,
tx dbtx.Transactor,
urlProvider urlprovider.Provider,
authorizer authz.Authorizer,
@ -71,8 +72,8 @@ func NewAPIController(
artifactStore store.ArtifactRepository,
webhooksRepository store.WebhooksRepository,
webhooksExecutionRepository store.WebhooksExecutionRepository,
registryMetadataHelper RegistryMetadataHelper,
webhookService WebhookService,
registryMetadataHelper interfaces.RegistryMetadataHelper,
webhookService webhook.ServiceInterface,
artifactEventReporter registryevents.Reporter,
downloadStatRepository store.DownloadStatRepository,
) *APIController {

View File

@ -79,7 +79,7 @@ func (c *APIController) CreateRegistry(
registry, upstreamproxy, err := c.CreateUpstreamProxyEntity(
ctx,
registryRequest,
regInfo.parentID, regInfo.rootIdentifierID,
regInfo.ParentID, regInfo.RootIdentifierID,
)
var registryID int64
if err != nil {
@ -127,16 +127,16 @@ func (c *APIController) CreateRegistry(
}
func (c *APIController) createVirtualRegistry(
ctx context.Context, registryRequest artifact.RegistryRequest, regInfo *RegistryRequestBaseInfo,
ctx context.Context, registryRequest artifact.RegistryRequest, regInfo *registrytypes.RegistryRequestBaseInfo,
session *auth.Session, parentRef artifact.SpaceRefPathParam,
) (artifact.CreateRegistryResponseObject, error) {
registry, err := CreateRegistryEntity(registryRequest, regInfo.parentID, regInfo.rootIdentifierID)
registry, err := CreateRegistryEntity(registryRequest, regInfo.ParentID, regInfo.RootIdentifierID)
if err != nil {
return throwCreateRegistry400Error(err), nil
}
if registry.PackageType != artifact.PackageTypeGENERIC {
err = c.setUpstreamProxyIDs(ctx, registry, registryRequest, regInfo.parentID)
err = c.setUpstreamProxyIDs(ctx, registry, registryRequest, regInfo.ParentID)
}
if err != nil {
return throwCreateRegistry400Error(err), nil
@ -332,7 +332,7 @@ func (c *APIController) CreateUpstreamProxyEntity(
}
if res.SecretSpacePath != nil && len(*res.SecretSpacePath) > 0 {
upstreamProxyConfigEntity.SecretSpaceID, err = c.RegistryMetadataHelper.getSecretSpaceID(ctx,
upstreamProxyConfigEntity.SecretSpaceID, err = c.RegistryMetadataHelper.GetSecretSpaceID(ctx,
res.SecretSpacePath)
if err != nil {
return nil, nil, err
@ -355,7 +355,7 @@ func (c *APIController) CreateUpstreamProxyEntity(
default:
if res.AccessKeySecretSpacePath != nil && len(*res.AccessKeySecretSpacePath) > 0 {
upstreamProxyConfigEntity.UserNameSecretSpaceID, err =
c.RegistryMetadataHelper.getSecretSpaceID(ctx, res.AccessKeySecretSpacePath)
c.RegistryMetadataHelper.GetSecretSpaceID(ctx, res.AccessKeySecretSpacePath)
if err != nil {
return nil, nil, err
}
@ -366,7 +366,7 @@ func (c *APIController) CreateUpstreamProxyEntity(
}
if res.SecretKeySpacePath != nil && len(*res.SecretKeySpacePath) > 0 {
upstreamProxyConfigEntity.SecretSpaceID, err = c.RegistryMetadataHelper.getSecretSpaceID(ctx,
upstreamProxyConfigEntity.SecretSpaceID, err = c.RegistryMetadataHelper.GetSecretSpaceID(ctx,
res.SecretKeySpacePath)
if err != nil {
return nil, nil, err

View File

@ -0,0 +1,483 @@
// 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.
//nolint:lll,revive // revive:disable:unused-parameter
package metadata_test
import (
"context"
"errors"
"fmt"
"testing"
"github.com/harness/gitness/app/api/request"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/events"
"github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/controller/mocks"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
registryevents "github.com/harness/gitness/registry/app/events"
"github.com/harness/gitness/registry/app/pkg/filemanager"
"github.com/harness/gitness/registry/types"
"github.com/harness/gitness/registry/utils"
coretypes "github.com/harness/gitness/types"
gitnessenum "github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
const (
// TestRegistryName is the name used for test registries.
testRegistryName = "test-registry"
)
var (
// ErrTestConsumerNotNeeded is a sentinel error indicating consumer is not needed in tests.
ErrTestConsumerNotNeeded = errors.New("consumer not needed in tests")
)
func TestCreateRegistry(t *testing.T) {
space := &coretypes.SpaceCore{
ID: 1,
Path: "root",
}
// Create mock event system components.
producer := &mocks.StreamProducer{}
// Set up producer expectations.
producer.On("Send", mock.Anything, "registry", mock.MatchedBy(func(payload map[string]interface{}) bool {
return payload["action"] == "registry.create" &&
payload["registry_id"] == int64(1) &&
payload["registry_name"] == testRegistryName
})).Return("", nil).Once()
// Create events system.
consumerFactory := func(_ string, _ string) (events.StreamConsumer, error) {
// Return a sentinel error to indicate consumer is not needed in tests.
return nil, ErrTestConsumerNotNeeded
}
eventsSystem, err := events.NewSystem(consumerFactory, producer)
if err != nil {
t.Fatalf("Failed to create events system: %v", err)
}
// Create event reporter.
reporter, err := registryevents.NewReporter(eventsSystem)
if err != nil {
t.Fatalf("Failed to create event reporter: %v", err)
}
eventReporter := *reporter // Use value instead of pointer.
// Helper mocks and setup complete.
tests := []struct {
name string
request api.CreateRegistryRequestObject
setupMocks func() *metadata.APIController
expectedResp interface{}
}{
{
name: "create_virtual_registry_success",
request: api.CreateRegistryRequestObject{
Body: &api.CreateRegistryJSONRequestBody{
Identifier: testRegistryName,
ParentRef: utils.StringPtr("root"),
Config: func() *api.RegistryConfig {
config := &api.RegistryConfig{Type: api.RegistryTypeVIRTUAL}
_ = config.FromVirtualConfig(api.VirtualConfig{UpstreamProxies: &[]string{}})
return config
}(),
PackageType: api.PackageTypeDOCKER,
CleanupPolicy: &[]api.CleanupPolicy{},
},
},
expectedResp: api.CreateRegistry201JSONResponse{
RegistryResponseJSONResponse: api.RegistryResponseJSONResponse{
Data: api.Registry{
Identifier: testRegistryName,
Config: &api.RegistryConfig{
Type: api.RegistryTypeVIRTUAL,
},
PackageType: api.PackageTypeDOCKER,
Url: "http://example.com/registry/test-registry",
Description: utils.StringPtr(""),
CreatedAt: utils.StringPtr("-62135596800000"),
ModifiedAt: utils.StringPtr("-62135596800000"),
},
Status: api.StatusSUCCESS,
},
},
setupMocks: func() *metadata.APIController {
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockRegistryRepo := new(mocks.RegistryRepository)
mockSpaceFinder := new(mocks.SpaceFinder)
mockAuthorizer := new(mocks.Authorizer)
mockAuditService := new(mocks.AuditService)
mockCleanupPolicyRepo := new(mocks.CleanupPolicyRepository)
mockTransactor := new(mocks.Transactor)
mockGenericBlobRepo := new(mocks.GenericBlobRepository)
// Create a mock URL provider.
mockURLProvider := new(mocks.Provider)
// Set up common URL provider expectations
mockURLProvider.On("PackageURL", mock.Anything, mock.Anything, mock.Anything,
mock.Anything).Return("http://example.com/registry/test-registry/docker")
mockURLProvider.On("GenerateUIRegistryURL", mock.Anything, mock.Anything,
mock.Anything).Return("http://example.com/registry/test-registry")
mockURLProvider.On("RegistryURL", mock.Anything, mock.Anything,
mock.Anything).Return("http://example.com/registry/test-registry")
// Setup base info mock.
baseInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: testRegistryName,
ParentRef: "root",
ParentID: 2,
RootIdentifierID: 3,
RootIdentifier: "root",
RegistryType: api.RegistryTypeVIRTUAL,
PackageType: api.PackageTypeDOCKER,
}
// Create the registry entity that will be used in mocks.
registry := &types.Registry{
ID: baseInfo.RegistryID,
Name: testRegistryName,
ParentID: baseInfo.ParentID,
RootParentID: baseInfo.RootIdentifierID,
Type: api.RegistryTypeVIRTUAL,
PackageType: api.PackageTypeDOCKER,
}
// 1. Mock the initial registry metadata lookup.
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "root", "").Return(baseInfo, nil).Once()
// 2. Mock the space lookup.
mockSpaceFinder.On("FindByRef", mock.Anything, "root").Return(space, nil).Once()
// 3. Mock the authorization check.
mockAuthorizer.On("Check", mock.Anything, mock.Anything,
mock.MatchedBy(func(scope *coretypes.Scope) bool { return scope.SpacePath == "root" }),
mock.MatchedBy(func(r *coretypes.Resource) bool { return r.Type == gitnessenum.ResourceTypeRegistry }),
gitnessenum.PermissionRegistryEdit).Return(true, nil).Once()
// 4. Mock registry creation
mockRegistryRepo.On("Create", mock.Anything,
mock.MatchedBy(func(r *types.Registry) bool {
return r.Name == testRegistryName &&
r.ParentID == baseInfo.ParentID &&
r.Type == api.RegistryTypeVIRTUAL &&
r.PackageType == api.PackageTypeDOCKER
})).Return(baseInfo.RegistryID, nil).Once()
// 5. Mock registry retrieval.
mockRegistryRepo.On("Get", mock.Anything, baseInfo.RegistryID).Return(registry, nil).Once()
// 6. Mock cleanup policy retrieval.
mockCleanupPolicyRepo.On("GetByRegistryID", mock.Anything,
baseInfo.RegistryID).Return(&[]types.CleanupPolicy{}, nil).Once()
// URL provider mock expectations set up above
// Mock setup already done above.
// Setup already covered above.
// Create file manager.
var app = &filemanager.App{
Context: context.Background(),
}
fileManager := filemanager.NewFileManager(
app,
mockRegistryRepo,
mockGenericBlobRepo,
nil, // nodesRepo - not needed for this test.
mockTransactor,
nil, // reporter - not needed for this test.
)
// Setup audit service mock.
mockAuditService.On("Log", mock.Anything,
mock.MatchedBy(func(p coretypes.Principal) bool { return p.ID == 1 && p.Type == "user" }),
mock.MatchedBy(func(r audit.Resource) bool {
return r.Type == audit.ResourceTypeRegistry && r.Identifier == testRegistryName
}),
audit.ActionCreated,
"root",
mock.Anything,
).Return(nil).Once()
// Setup registry repo mock.
mockRegistryRepo.On("FetchUpstreamProxyKeys", mock.Anything, mock.Anything).Return([]string{}, nil).Once()
mockCleanupPolicyRepo.On("GetByRegistryID", mock.Anything,
baseInfo.RegistryID).Return(&[]types.CleanupPolicy{}, nil).Once()
// Authorizer mock already setup above.
// Create controller.
// Setup transactor mock.
mockTransactor.On("WithTx", mock.Anything,
mock.AnythingOfType("func(context.Context) error"), mock.Anything).Run(func(args mock.Arguments) {
// Execute the transaction function.
txFn, ok := args.Get(1).(func(context.Context) error)
assert.True(t, ok, "Transaction function conversion failed")
err := txFn(context.Background())
// Check if an error occurs during transaction execution.
assert.NoError(t, err, "Transaction function should not return an error")
}).Return(nil)
// Create controller.
return metadata.NewAPIController(
mockRegistryRepo,
fileManager,
nil, // blobStore.
nil, // genericBlobStore.
nil, // upstreamProxyStore.
nil, // tagStore.
nil, // manifestStore.
mockCleanupPolicyRepo,
nil, // imageStore.
nil, // driver.
mockSpaceFinder,
mockTransactor,
mockURLProvider,
mockAuthorizer,
mockAuditService,
nil, // artifactStore.
nil, // webhooksRepository.
nil, // webhooksExecutionRepository.
mockRegistryMetadataHelper,
nil, // webhookService.
eventReporter,
nil, // downloadStatRepository.
)
},
},
{
name: "create_registry_invalid_parent",
request: api.CreateRegistryRequestObject{
Body: &api.CreateRegistryJSONRequestBody{
Identifier: testRegistryName,
ParentRef: utils.StringPtr("invalid"),
Config: func() *api.RegistryConfig {
config := &api.RegistryConfig{Type: api.RegistryTypeVIRTUAL}
_ = config.FromVirtualConfig(api.VirtualConfig{UpstreamProxies: &[]string{}})
return config
}(),
PackageType: api.PackageTypeDOCKER,
CleanupPolicy: &[]api.CleanupPolicy{},
},
},
expectedResp: api.CreateRegistry400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "space not found",
},
},
setupMocks: func() *metadata.APIController {
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockRegistryRepo := new(mocks.RegistryRepository)
mockTransactor := new(mocks.Transactor)
mockGenericBlobRepo := new(mocks.GenericBlobRepository)
// Setup error case mock.
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "invalid", "").
Return(nil, fmt.Errorf("space not found")).Once()
app := &filemanager.App{
Context: context.Background(),
}
fileManager := filemanager.NewFileManager(
app,
mockRegistryRepo,
mockGenericBlobRepo,
nil, // nodesRepo - not needed for this test.
mockTransactor,
nil, // reporter - not needed for this test.
)
return metadata.NewAPIController(
mockRegistryRepo,
fileManager,
nil, // blobStore.
nil, // genericBlobStore.
nil, // upstreamProxyStore.
nil, // tagStore.
nil, // manifestStore.
nil, // cleanupPolicyStore
nil, // imageStore.
nil, // driver.
nil, // spaceFinder
mockTransactor,
nil, // urlProvider.
nil, // authorizer.
nil, // auditService.
nil, // artifactStore.
nil, // webhooksRepository.
nil, // webhooksExecutionRepository.
mockRegistryMetadataHelper,
nil, // webhookService.
eventReporter,
nil, // downloadStatRepository.
)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create the controller.
controller := tt.setupMocks()
// Create context with auth session.
ctx := context.Background()
session := &auth.Session{
Principal: coretypes.Principal{
ID: 1,
Type: "user",
},
}
ctx = request.WithAuthSession(ctx, session)
// Call the API.
registryResp, err := controller.CreateRegistry(ctx, tt.request)
// Verify response matches expected type and content.
switch expected := tt.expectedResp.(type) {
case api.CreateRegistry201JSONResponse:
assert.NoError(t, err, "Expected no error but got one")
actualResp, ok := registryResp.(api.CreateRegistry201JSONResponse)
assert.True(t, ok, "Expected 201 response")
assert.Equal(t, expected.Status, actualResp.Status, "Response status should match")
// Verify registry data fields individually.
assert.Equal(t, expected.Data.Identifier, actualResp.Data.Identifier, "Registry identifier should match")
assert.Equal(t, expected.Data.PackageType, actualResp.Data.PackageType, "Package type should match")
assert.Equal(t, expected.Data.Url, actualResp.Data.Url, "Registry URL should match")
assert.Equal(t, expected.Data.Description, actualResp.Data.Description, "Description should match")
assert.Equal(t, expected.Data.CreatedAt, actualResp.Data.CreatedAt, "CreatedAt should match")
assert.Equal(t, expected.Data.ModifiedAt, actualResp.Data.ModifiedAt, "ModifiedAt should match")
// Verify config type.
assert.NotNil(t, actualResp.Data.Config, "Config should not be nil")
assert.Equal(t, expected.Data.Config.Type, actualResp.Data.Config.Type, "Config type should match")
// Verify mock expectations for success case.
called := controller.RegistryRepository.(*mocks.RegistryRepository).AssertCalled(t, "Create", //nolint:errcheck
mock.Anything, mock.MatchedBy(func(r *types.Registry) bool {
return r.Name == tt.request.Body.Identifier &&
r.Type == tt.request.Body.Config.Type &&
r.PackageType == tt.request.Body.PackageType
}))
assert.True(t, called, "Expected Create call not made")
// Verify all mocks expectations were met.
mockRegistry, regOk := controller.RegistryRepository.(*mocks.RegistryRepository)
assert.True(t, regOk, "Type assertion to RegistryRepository failed")
regAssertOk := mockRegistry.AssertExpectations(t)
assert.True(t, regAssertOk, "Mock expectations failed for RegistryRepository")
mockAudit, auditOk := controller.AuditService.(*mocks.AuditService)
assert.True(t, auditOk, "Type assertion to AuditService failed")
auditAssertOk := mockAudit.AssertExpectations(t)
assert.True(t, auditAssertOk, "Mock expectations failed for AuditService")
// Verify audit expectations.
logCalled := controller.AuditService.(*mocks.AuditService).AssertCalled(t, "Log", mock.Anything, //nolint:errcheck
mock.Anything, mock.Anything, audit.ActionCreated, mock.Anything, mock.Anything)
assert.True(t, logCalled, "Expected Log call not made")
case api.CreateRegistry400JSONResponse:
assert.Error(t, err, "Expected an error")
actualResp, ok := registryResp.(api.CreateRegistry400JSONResponse)
assert.True(t, ok, "Expected 400 response")
assert.Equal(t, expected.Code, actualResp.Code, "Error code should match")
assert.Equal(t, expected.Message, actualResp.Message, "Error message should match")
// Additional assertions for specific error cases.
switch tt.name {
case "create_registry_invalid_parent":
assert.Contains(t, actualResp.Message, "space not found",
"Error message should indicate invalid parent")
notCalled := controller.RegistryRepository.(*mocks.RegistryRepository).AssertNotCalled(t, //nolint:errcheck
"Create", mock.Anything, mock.Anything)
assert.True(t, notCalled, "Unexpected Create call made")
// Verify expectations for the error case.
metaHelper, metaHelperOk := controller.RegistryMetadataHelper.(*mocks.RegistryMetadataHelper)
assert.True(t, metaHelperOk, "Type assertion to RegistryMetadataHelper failed")
assertMetaOk := metaHelper.AssertExpectations(t)
assert.True(t, assertMetaOk, "Mock expectations failed for RegistryMetadataHelper")
case "create_registry_duplicate":
assert.Contains(t, actualResp.Message, "already defined",
"Error message should indicate duplicate registry")
assert.Contains(t, actualResp.Message, tt.request.Body.Identifier,
"Error message should include the registry identifier")
getByNameCalled := controller.RegistryRepository.(*mocks.RegistryRepository).AssertCalled(t, //nolint:errcheck
"GetByRootParentIDAndName", mock.Anything, mock.Anything, tt.request.Body.Identifier)
assert.True(t, getByNameCalled, "Expected GetByRootParentIDAndName call not made")
}
case api.CreateRegistry403JSONResponse:
assert.Error(t, err, "Expected an error")
actualResp, ok := registryResp.(api.CreateRegistry403JSONResponse)
assert.True(t, ok, "Expected 403 response")
assert.Equal(t, expected.Code, actualResp.Code, "Error code should match")
assert.Equal(t, expected.Message, actualResp.Message, "Error message should match")
assert.Contains(t, actualResp.Message, "unauthorized",
"Error message should indicate authorization failure")
_ = controller.RegistryRepository.(*mocks.RegistryRepository).AssertNotCalled(t, //nolint:errcheck
"Create", mock.Anything, mock.Anything)
default:
t.Fatalf("Unexpected response type: %T", tt.expectedResp)
}
// Verify common mock expectations.
if controller.RegistryRepository != nil {
registryRepo, regOk := controller.RegistryRepository.(*mocks.RegistryRepository)
assert.True(t, regOk, "Type assertion to RegistryRepository failed")
assertRegOk := registryRepo.AssertExpectations(t)
assert.True(t, assertRegOk, "Mock expectations failed for RegistryRepository")
}
if controller.RegistryMetadataHelper != nil {
metaHelper, metaHelperOk := controller.RegistryMetadataHelper.(*mocks.RegistryMetadataHelper)
assert.True(t, metaHelperOk, "Type assertion to RegistryMetadataHelper failed")
assertMetaOk := metaHelper.AssertExpectations(t)
assert.True(t, assertMetaOk, "Mock expectations failed for RegistryMetadataHelper")
}
if controller.SpaceFinder != nil {
spaceFinder, finderOk := controller.SpaceFinder.(*mocks.SpaceFinder)
assert.True(t, finderOk, "Type assertion to SpaceFinder failed")
spaceFinderOk := spaceFinder.AssertExpectations(t)
assert.True(t, spaceFinderOk, "Mock expectations failed for SpaceFinder")
}
if controller.Authorizer != nil {
auth, authOk := controller.Authorizer.(*mocks.Authorizer)
assert.True(t, authOk, "Type assertion to Authorizer failed")
authAssertOk := auth.AssertExpectations(t)
assert.True(t, authAssertOk, "Mock expectations failed for Authorizer")
}
if controller.AuditService != nil {
auditSvc, auditSvcOk := controller.AuditService.(*mocks.AuditService)
assert.True(t, auditSvcOk, "Type assertion to AuditService failed")
auditSvcAssertOk := auditSvc.AssertExpectations(t)
assert.True(t, auditSvcAssertOk, "Mock expectations failed for AuditService")
}
})
}
}

View File

@ -72,13 +72,14 @@ func (c *APIController) CreateWebhook(
}
webhook, err := c.RegistryMetadataHelper.MapToWebhookCore(ctx, webhookRequest, regInfo)
webhook.Type = enum.WebhookTypeExternal
webhook.CreatedBy = session.Principal.ID
if err != nil {
log.Ctx(ctx).Error().Msgf("failed to store webhook: %s with error: %v", webhookRequest.Identifier, err)
return createWebhookBadRequestErrorResponse(fmt.Errorf("failed to store webhook %w", err))
}
webhook.Type = enum.WebhookTypeExternal
webhook.CreatedBy = session.Principal.ID
err = c.WebhooksRepository.Create(ctx, webhook)
if err != nil {
log.Ctx(ctx).Error().Msgf("failed to store webhook: %s with error: %v", webhookRequest.Identifier, err)

View File

@ -0,0 +1,556 @@
// 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.
//nolint:lll,revive // revive:disable:unused-parameter
package metadata_test
import (
"context"
"fmt"
"testing"
apiauth "github.com/harness/gitness/app/api/auth"
"github.com/harness/gitness/app/api/request"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/controller/mocks"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
registrytypes "github.com/harness/gitness/registry/types"
"github.com/harness/gitness/registry/utils"
coretypes "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
const (
testWebhookIdentifier = "test-webhook"
testWebhookURL = "http://example.com"
)
func TestCreateWebhook(t *testing.T) {
tests := []struct {
name string
setupMocks func(*metadata.APIController)
request api.CreateWebhookRequestObject
expectedResp interface{}
expectedError error
}{
{
name: "success_case",
setupMocks: func(c *metadata.APIController) {
// Mock registry metadata helper
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockSpaceFinder := new(mocks.SpaceFinder)
mockWebhooksRepository := new(mocks.WebhooksRepository)
mockAuthorizer := new(mocks.Authorizer)
regInfo := &registrytypes.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
RegistryType: api.RegistryTypeVIRTUAL,
}
space := &coretypes.SpaceCore{
Path: "root/parent",
}
permissionChecks := []coretypes.PermissionCheck{
{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{
Type: enum.ResourceTypeRegistry,
Identifier: "reg",
},
Permission: enum.PermissionRegistryEdit,
},
}
webhook := &coretypes.WebhookCore{
ID: 1,
DisplayName: testWebhookIdentifier,
Identifier: testWebhookIdentifier,
URL: "http://example.com",
Enabled: true,
Insecure: false,
ParentID: regInfo.RegistryID,
Type: enum.WebhookTypeExternal,
}
webhookResponseEntity := &api.Webhook{
Identifier: "test-webhook",
Name: testWebhookIdentifier,
Url: "http://example.com",
Enabled: true,
Insecure: false,
CreatedAt: utils.StringPtr("2023-01-01T00:00:00Z"),
ModifiedAt: utils.StringPtr("2023-01-01T00:00:00Z"),
}
// Set up expectations.
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks",
mock.Anything,
"reg",
enum.PermissionRegistryEdit,
).Return(permissionChecks)
// Set up authorizer to expect a session with Principal ID 123 for success case
mockSession := &auth.Session{Principal: coretypes.Principal{ID: 123}}
mockAuthorizer.On("CheckAll", mock.Anything, mockSession, permissionChecks[0]).Return(true, nil)
mockRegistryMetadataHelper.On(
"MapToWebhookCore",
mock.Anything,
mock.MatchedBy(func(req api.WebhookRequest) bool {
return req.Identifier == testWebhookIdentifier &&
req.Name == testWebhookIdentifier &&
req.Url == testWebhookURL &&
req.Enabled == true &&
req.Insecure == false
}),
regInfo,
).Return(webhook, nil)
mockWebhooksRepository.On("Create", mock.Anything, webhook).Return(nil)
mockWebhooksRepository.On(
"GetByRegistryAndIdentifier",
mock.Anything,
regInfo.RegistryID,
"test-webhook",
).Return(webhook, nil)
mockRegistryMetadataHelper.On(
"MapToWebhookResponseEntity",
mock.Anything,
webhook,
).Return(webhookResponseEntity, nil)
// Assign mocks to controller
c.SpaceFinder = mockSpaceFinder
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.Authorizer = mockAuthorizer
c.WebhooksRepository = mockWebhooksRepository
},
request: api.CreateWebhookRequestObject{
RegistryRef: "reg",
Body: &api.CreateWebhookJSONRequestBody{
Name: testWebhookIdentifier,
Identifier: testWebhookIdentifier,
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
},
expectedResp: api.CreateWebhook201JSONResponse{
WebhookResponseJSONResponse: api.WebhookResponseJSONResponse{
Data: api.Webhook{
Name: "test-webhook",
Identifier: "test-webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
Status: api.StatusSUCCESS,
},
},
},
{
name: "reserved_identifier",
setupMocks: func(c *metadata.APIController) {
// 1. Mock registry metadata helper for GetRegistryRequestBaseInfo
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
regInfo := &registrytypes.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
RegistryType: api.RegistryTypeVIRTUAL,
}
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").
Return(regInfo, nil)
c.RegistryMetadataHelper = mockRegistryMetadataHelper
// 2. Mock SpaceFinder
mockSpaceFinder := new(mocks.SpaceFinder)
space := &coretypes.SpaceCore{
Path: "root/parent",
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
c.SpaceFinder = mockSpaceFinder
// 3. Mock GetPermissionChecks
permissionCheck := coretypes.PermissionCheck{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{
Type: enum.ResourceTypeRegistry,
Identifier: "reg",
},
Permission: enum.PermissionRegistryEdit,
}
mockRegistryMetadataHelper.On("GetPermissionChecks", mock.Anything, "reg", enum.PermissionRegistryEdit).
Return([]coretypes.PermissionCheck{permissionCheck})
// 4. Mock Authorizer
mockAuthorizer := new(mocks.Authorizer)
mockAuthorizer.On("CheckAll", mock.Anything, (*auth.Session)(nil), permissionCheck).Return(true, nil)
c.Authorizer = mockAuthorizer
// 5. Mock MapToWebhookCore
mockRegistryMetadataHelper.On("MapToWebhookCore", mock.Anything,
mock.MatchedBy(func(req api.WebhookRequest) bool {
return req.Identifier == "internal-webhook" &&
req.Name == "internal-webhook" &&
req.Url == testWebhookURL &&
req.Enabled == true &&
req.Insecure == false
}), regInfo).Return(nil, fmt.Errorf("webhook identifier internal-webhook is reserved"))
},
request: api.CreateWebhookRequestObject{
RegistryRef: "reg",
Body: &api.CreateWebhookJSONRequestBody{
Name: "internal-webhook",
Identifier: "internal-webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
},
expectedResp: api.CreateWebhook400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "failed to store webhook webhook identifier internal-webhook is reserved",
},
},
},
{
name: "invalid_registry_reference",
setupMocks: func(c *metadata.APIController) {
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "invalid-reg").
Return(nil, fmt.Errorf("invalid registry reference"))
c.RegistryMetadataHelper = mockRegistryMetadataHelper
},
request: api.CreateWebhookRequestObject{
RegistryRef: "invalid-reg",
Body: &api.CreateWebhookJSONRequestBody{
Name: "test-webhook",
Identifier: "test-webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
},
expectedResp: api.CreateWebhook400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "invalid registry reference",
},
},
},
{
name: "permission_check_fails",
setupMocks: func(c *metadata.APIController) {
// 1. Mock registry metadata helper for GetRegistryRequestBaseInfo
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
regInfo := &registrytypes.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
RegistryType: api.RegistryTypeVIRTUAL,
}
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").
Return(regInfo, nil)
// 2. Mock SpaceFinder
mockSpaceFinder := new(mocks.SpaceFinder)
space := &coretypes.SpaceCore{
Path: "root/parent",
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
c.SpaceFinder = mockSpaceFinder
// 3. Mock GetPermissionChecks
permissionCheck := coretypes.PermissionCheck{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{
Type: enum.ResourceTypeRegistry,
Identifier: "reg",
},
Permission: enum.PermissionRegistryEdit,
}
mockRegistryMetadataHelper.On("GetPermissionChecks", mock.Anything, "reg", enum.PermissionRegistryEdit).
Return([]coretypes.PermissionCheck{permissionCheck})
c.RegistryMetadataHelper = mockRegistryMetadataHelper
// Mock authorizer with manual response
mockAuthorizer := new(mocks.Authorizer)
mockAuthorizer.On("CheckAll", mock.Anything, (*auth.Session)(nil), permissionCheck).Return(false, apiauth.ErrUnauthorized)
c.Authorizer = mockAuthorizer
},
request: api.CreateWebhookRequestObject{
RegistryRef: "reg",
Body: &api.CreateWebhookJSONRequestBody{
Name: testWebhookIdentifier,
Identifier: testWebhookIdentifier,
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
},
expectedResp: api.CreateWebhook403JSONResponse{
UnauthorizedJSONResponse: api.UnauthorizedJSONResponse{
Code: "403",
Message: "unauthorized",
},
},
},
{
name: "non_virtual_registry",
setupMocks: func(c *metadata.APIController) {
// 1. Mock registry metadata helper for GetRegistryRequestBaseInfo
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
regInfo := &registrytypes.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
RegistryType: api.RegistryTypeUPSTREAM,
}
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").
Return(regInfo, nil)
c.RegistryMetadataHelper = mockRegistryMetadataHelper
},
request: api.CreateWebhookRequestObject{
RegistryRef: "reg",
Body: &api.CreateWebhookJSONRequestBody{
Name: testWebhookIdentifier,
Identifier: testWebhookIdentifier,
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
},
expectedResp: api.CreateWebhook400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "not allowed to create webhook for UPSTREAM registry",
},
},
},
{
name: "permission_check_fails",
setupMocks: func(c *metadata.APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockAuthorizer := new(mocks.Authorizer)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &registrytypes.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
RegistryType: api.RegistryTypeVIRTUAL,
}
permissionChecks := []coretypes.PermissionCheck{
{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{Type: enum.ResourceTypeRegistry, Identifier: "reg"},
Permission: enum.PermissionRegistryEdit,
},
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").
Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").
Return(regInfo, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, "reg", enum.PermissionRegistryEdit).
Return(permissionChecks)
mockAuthorizer.On("CheckAll", mock.Anything, (*auth.Session)(nil), permissionChecks[0]).
Return(false, fmt.Errorf("unauthorized"))
c.SpaceFinder = mockSpaceFinder
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.Authorizer = mockAuthorizer
},
request: api.CreateWebhookRequestObject{
RegistryRef: "reg",
Body: &api.CreateWebhookJSONRequestBody{
Name: testWebhookIdentifier,
Identifier: testWebhookIdentifier,
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
},
expectedResp: api.CreateWebhook403JSONResponse{
UnauthorizedJSONResponse: api.UnauthorizedJSONResponse{
Code: "403",
Message: "unauthorized",
},
},
},
{
name: "duplicate_webhook_identifier",
setupMocks: func(c *metadata.APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockAuthorizer := new(mocks.Authorizer)
mockWebhooksRepository := new(mocks.WebhooksRepository)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &registrytypes.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
RegistryType: api.RegistryTypeVIRTUAL,
}
permissionChecks := []coretypes.PermissionCheck{
{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{Type: enum.ResourceTypeRegistry, Identifier: "reg"},
Permission: enum.PermissionRegistryEdit,
},
}
webhook := &coretypes.WebhookCore{
ID: 1,
Type: enum.WebhookTypeExternal,
CreatedBy: 0,
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").
Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").
Return(regInfo, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, "reg", enum.PermissionRegistryEdit).
Return(permissionChecks)
// Set up authorizer to expect a session with Principal ID 123 for this test case
mockSession := &auth.Session{Principal: coretypes.Principal{ID: 123}}
mockAuthorizer.On("CheckAll", mock.Anything, mockSession, permissionChecks[0]).
Return(true, nil)
mockRegistryMetadataHelper.On("MapToWebhookCore", mock.Anything,
mock.MatchedBy(func(req api.WebhookRequest) bool {
return req.Identifier == testWebhookIdentifier &&
req.Name == testWebhookIdentifier &&
req.Url == testWebhookURL &&
req.Enabled == true &&
req.Insecure == false
}), regInfo).
Return(webhook, nil)
mockWebhooksRepository.On("Create", mock.Anything, webhook).
Return(fmt.Errorf("resource is a duplicate"))
c.SpaceFinder = mockSpaceFinder
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.Authorizer = mockAuthorizer
c.WebhooksRepository = mockWebhooksRepository
},
request: api.CreateWebhookRequestObject{
RegistryRef: "reg",
Body: &api.CreateWebhookJSONRequestBody{
Name: testWebhookIdentifier,
Identifier: testWebhookIdentifier,
Url: "http://example.com",
Enabled: true,
Insecure: false,
},
},
expectedResp: api.CreateWebhook400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "failed to store webhook, Webhook with identifier test-webhook already exists",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create controller and setup mocks.
controller := &metadata.APIController{}
tt.setupMocks(controller)
// Create a context with auth session for success case
localCtx := context.Background()
// Add auth session for tests that need it to set CreatedBy field
if tt.name == "success_case" || tt.name == "duplicate_webhook_identifier" {
mockPrincipal := coretypes.Principal{ID: 123}
mockSession := &auth.Session{Principal: mockPrincipal}
localCtx = request.WithAuthSession(localCtx, mockSession)
}
// Execute.
resp, err := controller.CreateWebhook(localCtx, tt.request)
// Verify response matches expected type and content.
switch expected := tt.expectedResp.(type) {
case api.CreateWebhook201JSONResponse:
assert.NoError(t, err, "Expected no error but got one")
actualResp, ok := resp.(api.CreateWebhook201JSONResponse)
assert.True(t, ok, "Expected 201 response")
// Verify webhook data fields individually.
assert.Equal(t, expected.Data.Identifier, actualResp.Data.Identifier, "Webhook identifier should match")
assert.Equal(t, expected.Data.Name, actualResp.Data.Name, "Webhook name should match")
assert.Equal(t, expected.Data.Url, actualResp.Data.Url, "Webhook URL should match")
assert.Equal(t, expected.Data.Enabled, actualResp.Data.Enabled, "Enabled status should match")
assert.Equal(t, expected.Data.Insecure, actualResp.Data.Insecure, "Insecure status should match")
assert.NotEmpty(t, actualResp.Data.CreatedAt, "CreatedAt should not be empty")
assert.NotEmpty(t, actualResp.Data.ModifiedAt, "ModifiedAt should not be empty")
assert.Equal(t, api.StatusSUCCESS, actualResp.Status, "Status should be SUCCESS")
case api.CreateWebhook400JSONResponse:
// For error responses, we don't need to check the err value since responses with error codes are still valid responses
actualResp, ok := resp.(api.CreateWebhook400JSONResponse)
assert.True(t, ok, "Expected 400 response")
assert.Equal(t, expected.Code, actualResp.Code, "Error code should match")
assert.Equal(t, expected.Message, actualResp.Message, "Error message should match")
case api.CreateWebhook403JSONResponse:
// For error responses, we don't need to check the err value since responses with error codes are still valid responses
actualResp, ok := resp.(api.CreateWebhook403JSONResponse)
assert.True(t, ok, "Expected 403 response")
assert.Equal(t, expected.Code, actualResp.Code, "Error code should match")
assert.Equal(t, expected.Message, actualResp.Message, "Error message should match")
default:
t.Fatalf("Unexpected response type: %T", tt.expectedResp)
}
// Verify mock expectations
if mockSpaceFinder, ok := controller.SpaceFinder.(*mocks.SpaceFinder); ok {
mockSpaceFinder.AssertExpectations(t)
}
if mockMetadataHelper, ok := controller.RegistryMetadataHelper.(*mocks.RegistryMetadataHelper); ok {
mockMetadataHelper.AssertExpectations(t)
}
if mockWebhooksRepo, ok := controller.WebhooksRepository.(*mocks.WebhooksRepository); ok {
mockWebhooksRepo.AssertExpectations(t)
}
if mockAuditService, ok := controller.AuditService.(*mocks.AuditService); ok {
mockAuditService.AssertExpectations(t)
}
})
}
}

View File

@ -24,6 +24,7 @@ import (
"github.com/harness/gitness/audit"
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/api/utils"
registryTypes "github.com/harness/gitness/registry/types"
"github.com/harness/gitness/types/enum"
"github.com/rs/zerolog/log"
@ -64,7 +65,7 @@ func (c *APIController) DeleteArtifact(ctx context.Context, r artifact.DeleteArt
}, err
}
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
//nolint:nilerr
return artifact.DeleteArtifact404JSONResponse{
@ -130,7 +131,7 @@ func (c *APIController) DeleteArtifact(ctx context.Context, r artifact.DeleteArt
func (c *APIController) deleteOCIImage(
ctx context.Context,
regInfo *RegistryRequestBaseInfo,
regInfo *registryTypes.RegistryRequestBaseInfo,
artifactName string,
) error {
err := c.tx.WithTx(
@ -156,7 +157,7 @@ func (c *APIController) deleteOCIImage(
func (c *APIController) deleteGenericImage(
ctx context.Context,
regInfo *RegistryRequestBaseInfo,
regInfo *registryTypes.RegistryRequestBaseInfo,
artifactName string,
) error {
err := c.tx.WithTx(

View File

@ -0,0 +1,458 @@
// 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"
"github.com/harness/gitness/app/api/request"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/registry/app/api/controller/mocks"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/types"
coretypes "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
func TestDeleteArtifact(t *testing.T) {
// Create a mock session for testing
principal := coretypes.Principal{
ID: 1,
Type: enum.PrincipalTypeUser,
Email: "test@example.com",
}
mockSession := &auth.Session{
Principal: principal,
}
// Create a context with the mock session
testCtx := request.WithAuthSession(context.Background(), mockSession)
tests := []struct {
name string
setupMocks func(*APIController)
request api.DeleteArtifactRequestObject
expectedResp api.DeleteArtifactResponseObject
expectedError error
}{
{
name: "success_case",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockImageStore := new(mocks.ImageRepository)
mockTx := new(mocks.Transaction)
mockAuditService := new(mocks.AuditService)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
PackageType: api.PackageTypePYTHON,
}
registry := &types.Registry{
ID: 1,
Name: "reg",
ParentID: 2,
Type: "native",
PackageType: "pypi",
}
artifact := &types.Image{
ID: 1,
Name: "test-artifact",
Enabled: true,
RegistryID: regInfo.RegistryID,
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo",
mock.Anything, "", "reg").Return(regInfo, nil)
mockAuthorizer.On(
"Check",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
mock.AnythingOfType("*types.Scope"),
mock.AnythingOfType("*types.Resource"),
enum.PermissionArtifactsDelete,
).Return(true, nil)
mockRegistryRepository.On(
"GetByParentIDAndName",
mock.Anything,
int64(2),
"reg",
).Return(registry, nil)
mockImageStore.On(
"GetByName",
mock.Anything,
int64(1),
"test-artifact",
).Return(artifact, nil)
mockTx.On("WithTx", mock.Anything, mock.AnythingOfType("func(context.Context) error")).Return(nil)
mockAuditService.On(
"Log",
mock.Anything,
mock.AnythingOfType("types.Principal"),
mock.AnythingOfType("audit.Resource"),
audit.ActionDeleted,
"root/parent",
mock.Anything,
mock.Anything,
).Return(nil)
c.SpaceFinder = mockSpaceFinder
c.RegistryRepository = mockRegistryRepository
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.ImageStore = mockImageStore
c.tx = mockTx
c.AuditService = mockAuditService
},
request: api.DeleteArtifactRequestObject{
RegistryRef: "reg",
Artifact: "test-artifact",
},
expectedResp: api.DeleteArtifact200JSONResponse{
SuccessJSONResponse: api.SuccessJSONResponse{
Status: api.StatusSUCCESS,
},
},
},
{
name: "invalid_registry_reference",
setupMocks: func(c *APIController) {
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo",
mock.Anything, "", "invalid-reg").Return(nil, fmt.Errorf("invalid registry reference"))
c.RegistryMetadataHelper = mockRegistryMetadataHelper
},
request: api.DeleteArtifactRequestObject{
RegistryRef: "invalid-reg",
Artifact: "test-artifact",
},
expectedResp: api.DeleteArtifact400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "invalid registry reference",
},
},
expectedError: fmt.Errorf("invalid registry reference"),
},
{
name: "permission_check_fails",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockAuthorizer := new(mocks.Authorizer)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
PackageType: api.PackageTypePYTHON,
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo",
mock.Anything, "", "reg").Return(regInfo, nil)
mockAuthorizer.On("Check", mock.Anything, mock.AnythingOfType("*auth.Session"),
mock.AnythingOfType("*types.Scope"),
mock.AnythingOfType("*types.Resource"),
enum.PermissionArtifactsDelete).Return(false, fmt.Errorf("not authorized"))
c.SpaceFinder = mockSpaceFinder
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.Authorizer = mockAuthorizer
},
request: api.DeleteArtifactRequestObject{
RegistryRef: "reg",
Artifact: "test-artifact",
},
expectedResp: api.DeleteArtifact403JSONResponse{
UnauthorizedJSONResponse: api.UnauthorizedJSONResponse{
Code: "403",
Message: "not authorized",
},
},
expectedError: fmt.Errorf("not authorized"),
},
{
name: "registry_not_found",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
PackageType: api.PackageTypePYTHON,
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo",
mock.Anything, "", "reg").Return(regInfo, nil)
mockAuthorizer.On(
"Check",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
mock.AnythingOfType("*types.Scope"),
mock.AnythingOfType("*types.Resource"),
enum.PermissionArtifactsDelete,
).Return(true, nil)
mockRegistryRepository.On(
"GetByParentIDAndName",
mock.Anything,
int64(2),
"reg",
).Return(nil, fmt.Errorf("registry doesn't exist with this key"))
c.SpaceFinder = mockSpaceFinder
c.RegistryRepository = mockRegistryRepository
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
},
request: api.DeleteArtifactRequestObject{
RegistryRef: "reg",
Artifact: "test-artifact",
},
expectedResp: api.DeleteArtifact404JSONResponse{
NotFoundJSONResponse: api.NotFoundJSONResponse{
Code: "404",
Message: "registry doesn't exist with this key",
},
},
},
{
name: "artifact_not_found",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockImageStore := new(mocks.ImageRepository)
mockAuditService := new(mocks.AuditService)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
PackageType: api.PackageTypePYTHON,
}
registry := &types.Registry{
ID: 1,
Name: "reg",
ParentID: 2,
Type: "native",
PackageType: "pypi",
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo",
mock.Anything, "", "reg").Return(regInfo, nil)
mockAuthorizer.On(
"Check",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
mock.AnythingOfType("*types.Scope"),
mock.AnythingOfType("*types.Resource"),
enum.PermissionArtifactsDelete,
).Return(true, nil)
mockRegistryRepository.On(
"GetByParentIDAndName",
mock.Anything,
int64(2),
"reg",
).Return(registry, nil)
mockImageStore.On(
"GetByName",
mock.Anything,
int64(1),
"non-existent-artifact",
).Return(nil, fmt.Errorf("artifact doesn't exist with this key"))
c.SpaceFinder = mockSpaceFinder
c.RegistryRepository = mockRegistryRepository
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.ImageStore = mockImageStore
c.AuditService = mockAuditService
},
request: api.DeleteArtifactRequestObject{
RegistryRef: "reg",
Artifact: "non-existent-artifact",
},
expectedResp: api.DeleteArtifact404JSONResponse{
NotFoundJSONResponse: api.NotFoundJSONResponse{
Code: "404",
Message: "artifact doesn't exist with this key",
},
},
},
{
name: "artifact_already_deleted",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockImageStore := new(mocks.ImageRepository)
mockAuditService := new(mocks.AuditService)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
PackageType: api.PackageTypePYTHON,
}
registry := &types.Registry{
ID: 1,
Name: "reg",
ParentID: 2,
Type: "native",
PackageType: "pypi",
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo",
mock.Anything, "", "reg").Return(regInfo, nil)
mockAuthorizer.On(
"Check",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
mock.AnythingOfType("*types.Scope"),
mock.AnythingOfType("*types.Resource"),
enum.PermissionArtifactsDelete,
).Return(true, nil)
mockRegistryRepository.On(
"GetByParentIDAndName",
mock.Anything,
int64(2),
"reg",
).Return(registry, nil)
mockImageStore.On(
"GetByName",
mock.Anything,
int64(1),
"deleted-artifact",
).Return(nil, fmt.Errorf("artifact is already deleted"))
c.SpaceFinder = mockSpaceFinder
c.RegistryRepository = mockRegistryRepository
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.ImageStore = mockImageStore
c.AuditService = mockAuditService
},
request: api.DeleteArtifactRequestObject{
RegistryRef: "reg",
Artifact: "deleted-artifact",
},
expectedResp: api.DeleteArtifact404JSONResponse{
NotFoundJSONResponse: api.NotFoundJSONResponse{
Code: "404",
Message: "artifact doesn't exist with this key",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &APIController{}
tt.setupMocks(c)
// Use the test context with the mock session
resp, err := c.DeleteArtifact(testCtx, tt.request)
if tt.expectedError != nil {
assert.Error(t, err, "Expected an error")
assert.Equal(t, tt.expectedError.Error(), err.Error(), "Error message should match")
} else {
assert.NoError(t, err, "Expected no error")
}
// Check response type
switch expected := tt.expectedResp.(type) {
case api.DeleteArtifact200JSONResponse:
actual, ok := resp.(api.DeleteArtifact200JSONResponse)
assert.True(t, ok, "Expected 200 success response")
assert.Equal(t, expected.Status, actual.Status, "Response status should match")
case api.DeleteArtifact400JSONResponse:
actual, ok := resp.(api.DeleteArtifact400JSONResponse)
assert.True(t, ok, "Expected 400 bad request response")
assert.Equal(t, expected.Message, actual.Message, "Error message should match")
case api.DeleteArtifact403JSONResponse:
actual, ok := resp.(api.DeleteArtifact403JSONResponse)
assert.True(t, ok, "Expected 403 forbidden response")
assert.Equal(t, expected.Message, actual.Message, "Error message should match")
case api.DeleteArtifact404JSONResponse:
actual, ok := resp.(api.DeleteArtifact404JSONResponse)
assert.True(t, ok, "Expected 404 not found response")
assert.Equal(t, expected.Message, actual.Message, "Error message should match")
}
// Full response should match expected value
assert.Equal(t, tt.expectedResp, resp, "Full response should match expected value")
// Verify all expectations were met
// Only verify mocks that were actually set up in this test case
if c.SpaceFinder != nil {
mock.AssertExpectationsForObjects(t, c.SpaceFinder)
}
if c.RegistryRepository != nil {
mock.AssertExpectationsForObjects(t, c.RegistryRepository)
}
if c.Authorizer != nil {
mock.AssertExpectationsForObjects(t, c.Authorizer)
}
if c.RegistryMetadataHelper != nil {
mock.AssertExpectationsForObjects(t, c.RegistryMetadataHelper)
}
if c.ImageStore != nil {
mock.AssertExpectationsForObjects(t, c.ImageStore)
}
if c.tx != nil {
mock.AssertExpectationsForObjects(t, c.tx)
}
if c.AuditService != nil {
mock.AssertExpectationsForObjects(t, c.AuditService)
}
})
}
}

View File

@ -25,6 +25,7 @@ import (
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/api/utils"
"github.com/harness/gitness/registry/services/webhook"
registryTypes "github.com/harness/gitness/registry/types"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
@ -67,7 +68,7 @@ func (c *APIController) DeleteArtifactVersion(ctx context.Context, r artifact.De
}, err
}
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
//nolint:nilerr
return artifact.DeleteArtifactVersion404JSONResponse{
@ -81,7 +82,7 @@ func (c *APIController) DeleteArtifactVersion(ctx context.Context, r artifact.De
versionName := string(r.Version)
registryName := repoEntity.Name
image, err := c.ImageStore.GetByRepoAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier, artifactName)
image, err := c.ImageStore.GetByRepoAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier, artifactName)
if err != nil {
//nolint:nilerr
return artifact.DeleteArtifactVersion404JSONResponse{
@ -103,10 +104,10 @@ func (c *APIController) DeleteArtifactVersion(ctx context.Context, r artifact.De
switch regInfo.PackageType {
case artifact.PackageTypeDOCKER:
err = c.deleteTag(ctx, regInfo, registryName, session.Principal, artifactName,
err = c.deleteTagWithAudit(ctx, regInfo, registryName, session.Principal, artifactName,
versionName)
case artifact.PackageTypeHELM:
err = c.deleteTag(ctx, regInfo, registryName, session.Principal, artifactName,
err = c.deleteTagWithAudit(ctx, regInfo, registryName, session.Principal, artifactName,
versionName)
case artifact.PackageTypeNPM:
err = c.deleteVersion(ctx, regInfo, artifactName, versionName)
@ -147,8 +148,8 @@ func (c *APIController) DeleteArtifactVersion(ctx context.Context, r artifact.De
}, nil
}
func (c *APIController) deleteTag(
ctx context.Context, regInfo *RegistryRequestBaseInfo,
func (c *APIController) deleteTagWithAudit(
ctx context.Context, regInfo *registryTypes.RegistryRequestBaseInfo,
registryName string, principal types.Principal, artifactName string, versionName string,
) error {
existingDigest := c.getTagDigest(ctx, regInfo.RegistryID, artifactName, versionName)
@ -170,7 +171,7 @@ func (c *APIController) deleteTag(
func (c *APIController) deleteVersion(
ctx context.Context,
regInfo *RegistryRequestBaseInfo,
regInfo *registryTypes.RegistryRequestBaseInfo,
artifactName string,
versionName string,
) error {

View File

@ -69,7 +69,7 @@ func (c *APIController) DeleteRegistry(
}, err
}
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
//nolint:nilerr
return artifact.DeleteRegistry404JSONResponse{
@ -132,10 +132,10 @@ func (c *APIController) DeleteRegistry(
func (c *APIController) deleteUpstreamProxyWithAudit(
ctx context.Context,
regInfo *RegistryRequestBaseInfo, principal types.Principal, parentRef string, registryName string,
regInfo *registrytypes.RegistryRequestBaseInfo, principal types.Principal, parentRef string, registryName string,
) error {
upstreamProxies, err := c.RegistryRepository.FetchUpstreamProxyIDs(ctx,
[]string{regInfo.RegistryIdentifier}, regInfo.parentID)
[]string{regInfo.RegistryIdentifier}, regInfo.ParentID)
if err != nil {
log.Ctx(ctx).Error().Msgf("failed to fetch upstream proxy IDs: %s", err)
return fmt.Errorf("failed to fectch upstream proxy IDs :%w", err)
@ -143,7 +143,7 @@ func (c *APIController) deleteUpstreamProxyWithAudit(
//nolint:nestif
if len(upstreamProxies) > 0 {
registryIDs, err := c.RegistryRepository.FetchRegistriesIDByUpstreamProxyID(
ctx, strconv.FormatInt(upstreamProxies[0], 10), regInfo.rootIdentifierID)
ctx, strconv.FormatInt(upstreamProxies[0], 10), regInfo.RootIdentifierID)
if err != nil {
log.Ctx(ctx).Error().Msgf("failed to fetch registryIDs: %s", err)
return fmt.Errorf("failed to fetch registryIDs IDs :%w", err)
@ -168,7 +168,7 @@ func (c *APIController) deleteUpstreamProxyWithAudit(
}
}
err = c.UpstreamProxyStore.Delete(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
err = c.UpstreamProxyStore.Delete(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return err
}
@ -191,7 +191,7 @@ func (c *APIController) deleteUpstreamProxyWithAudit(
}
func (c *APIController) deleteRegistryWithAudit(
ctx context.Context, regInfo *RegistryRequestBaseInfo,
ctx context.Context, regInfo *registrytypes.RegistryRequestBaseInfo,
registry *registrytypes.Registry, principal types.Principal, parentRef string,
) error {
err := c.ImageStore.DeleteByRegistryID(ctx, regInfo.RegistryID)
@ -204,7 +204,7 @@ func (c *APIController) deleteRegistryWithAudit(
return err
}
err = c.RegistryRepository.Delete(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
err = c.RegistryRepository.Delete(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return err
}

View File

@ -0,0 +1,475 @@
// 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"
"github.com/harness/gitness/app/api/request"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/registry/app/api/controller/mocks"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/types"
coretypes "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
func TestDeleteRegistry(t *testing.T) {
// Create a mock session for testing
principal := coretypes.Principal{
ID: 1,
Type: enum.PrincipalTypeUser,
Email: "test@example.com",
}
mockSession := &auth.Session{
Principal: principal,
}
// Create a context with the mock session
testCtx := request.WithAuthSession(context.Background(), mockSession)
tests := []struct {
name string
setupMocks func(*APIController)
request api.DeleteRegistryRequestObject
expectedResp api.DeleteRegistryResponseObject
expectedError error
}{
{
name: "success_case_virtual_registry",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockImageStore := new(mocks.ImageRepository)
mockTx := new(mocks.Transaction)
mockAuditService := new(mocks.AuditService)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
registry := &types.Registry{
ID: 1,
Name: "reg",
ParentID: 2,
Type: "virtual",
PackageType: "pypi",
}
permissionChecks := []coretypes.PermissionCheck{
{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{Type: enum.ResourceTypeRegistry, Identifier: "reg"},
Permission: enum.PermissionRegistryDelete,
},
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks",
space,
"reg",
enum.PermissionRegistryDelete,
).Return(permissionChecks)
mockAuthorizer.On(
"CheckAll",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
permissionChecks[0],
).Return(true, nil)
mockRegistryRepository.On(
"GetByParentIDAndName",
mock.Anything,
regInfo.ParentID,
regInfo.RegistryIdentifier,
).Return(registry, nil)
mockImageStore.On("DeleteDownloadStatByRegistryID", mock.Anything, regInfo.RegistryID).Return(nil)
mockImageStore.On("DeleteBandwidthStatByRegistryID", mock.Anything, regInfo.RegistryID).Return(nil)
mockImageStore.On("DeleteByRegistryID", mock.Anything, regInfo.RegistryID).Return(nil)
mockRegistryRepository.On("Delete", mock.Anything, regInfo.ParentID, regInfo.RegistryIdentifier).Return(nil)
mockAuditService.On(
"Log",
mock.Anything,
mock.AnythingOfType("*types.PrincipalInfo"),
mock.AnythingOfType("*audit.Resource"),
mock.AnythingOfType("string"),
mock.AnythingOfType("string"),
mock.AnythingOfType("audit.Option"),
).Return(nil)
// Simply return nil for the transaction - we're testing the controller logic, not transaction details
mockTx.On("WithTx", mock.Anything, mock.AnythingOfType("func(context.Context) error")).Return(nil)
c.SpaceFinder = mockSpaceFinder
c.RegistryRepository = mockRegistryRepository
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.ImageStore = mockImageStore
c.tx = mockTx
c.AuditService = mockAuditService
},
request: api.DeleteRegistryRequestObject{
RegistryRef: "reg",
},
expectedResp: api.DeleteRegistry200JSONResponse{
SuccessJSONResponse: api.SuccessJSONResponse{
Status: api.StatusSUCCESS,
},
},
},
{
name: "invalid_registry_reference",
setupMocks: func(c *APIController) {
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockRegistryMetadataHelper.On(
"GetRegistryRequestBaseInfo",
mock.Anything,
"",
"invalid-reg",
).Return(nil, fmt.Errorf("invalid registry reference"))
c.RegistryMetadataHelper = mockRegistryMetadataHelper
},
request: api.DeleteRegistryRequestObject{
RegistryRef: "invalid-reg",
},
expectedResp: api.DeleteRegistry400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "invalid registry reference",
},
},
expectedError: fmt.Errorf("invalid registry reference"),
},
{
name: "permission_check_fails",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockAuthorizer := new(mocks.Authorizer)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
permissionChecks := []coretypes.PermissionCheck{
{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{Type: enum.ResourceTypeRegistry, Identifier: "reg"},
Permission: enum.PermissionRegistryDelete,
},
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks",
space,
"reg",
enum.PermissionRegistryDelete,
).Return(permissionChecks)
mockAuthorizer.On(
"CheckAll",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
permissionChecks[0],
).Return(false, fmt.Errorf("not authorized"))
c.SpaceFinder = mockSpaceFinder
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.Authorizer = mockAuthorizer
},
request: api.DeleteRegistryRequestObject{
RegistryRef: "reg",
},
expectedResp: api.DeleteRegistry403JSONResponse{
UnauthorizedJSONResponse: api.UnauthorizedJSONResponse{
Code: "403",
Message: "not authorized",
},
},
expectedError: fmt.Errorf("not authorized"),
},
{
name: "registry_not_found",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
permissionChecks := []coretypes.PermissionCheck{
{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{Type: enum.ResourceTypeRegistry, Identifier: "reg"},
Permission: enum.PermissionRegistryDelete,
},
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks",
space,
"reg",
enum.PermissionRegistryDelete,
).Return(permissionChecks)
mockAuthorizer.On(
"CheckAll",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
permissionChecks[0],
).Return(true, nil)
mockRegistryRepository.On(
"GetByParentIDAndName",
mock.Anything,
regInfo.ParentID,
regInfo.RegistryIdentifier,
).Return(nil, fmt.Errorf("registry doesn't exist with this key"))
c.SpaceFinder = mockSpaceFinder
c.RegistryRepository = mockRegistryRepository
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
},
request: api.DeleteRegistryRequestObject{
RegistryRef: "reg",
},
expectedResp: api.DeleteRegistry404JSONResponse{
NotFoundJSONResponse: api.NotFoundJSONResponse{
Code: "404",
Message: "registry doesn't exist with this key",
},
},
},
{
name: "success_case_native_registry",
setupMocks: func(c *APIController) {
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockImageStore := new(mocks.ImageRepository)
mockTx := new(mocks.Transaction)
mockAuditService := new(mocks.AuditService)
mockUpstreamProxyStore := new(mocks.UpstreamProxyStore)
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
registry := &types.Registry{
ID: 1,
Name: "reg",
ParentID: 2,
Type: "native",
PackageType: "pypi",
}
permissionChecks := []coretypes.PermissionCheck{
{
Scope: coretypes.Scope{SpacePath: "root/parent"},
Resource: coretypes.Resource{Type: enum.ResourceTypeRegistry, Identifier: "reg"},
Permission: enum.PermissionRegistryDelete,
},
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks",
space,
"reg",
enum.PermissionRegistryDelete,
).Return(permissionChecks)
mockAuthorizer.On(
"CheckAll",
mock.Anything,
mock.AnythingOfType("*auth.Session"),
permissionChecks[0],
).Return(true, nil)
mockRegistryRepository.On(
"GetByParentIDAndName",
mock.Anything,
regInfo.ParentID,
regInfo.RegistryIdentifier,
).Return(registry, nil)
mockRegistryRepository.On(
"FetchUpstreamProxyIDs",
mock.Anything,
[]string{regInfo.RegistryIdentifier},
regInfo.ParentID,
).Return([]int64{}, nil)
mockUpstreamProxyStore.On("Delete", mock.Anything, regInfo.ParentID, regInfo.RegistryIdentifier).Return(nil)
mockImageStore.On("DeleteDownloadStatByRegistryID", mock.Anything, regInfo.RegistryID).Return(nil)
mockImageStore.On("DeleteBandwidthStatByRegistryID", mock.Anything, regInfo.RegistryID).Return(nil)
mockImageStore.On("DeleteByRegistryID", mock.Anything, regInfo.RegistryID).Return(nil)
mockRegistryRepository.On("Delete", mock.Anything, regInfo.ParentID, regInfo.RegistryIdentifier).Return(nil)
mockAuditService.On(
"Log",
mock.Anything,
mock.AnythingOfType("*types.PrincipalInfo"),
mock.AnythingOfType("*audit.Resource"),
mock.AnythingOfType("string"),
mock.AnythingOfType("string"),
mock.AnythingOfType("audit.Option"),
).Return(nil)
// Simply return nil for the transaction - we're testing the controller logic, not transaction details
mockTx.On("WithTx", mock.Anything, mock.AnythingOfType("func(context.Context) error")).Return(nil)
c.SpaceFinder = mockSpaceFinder
c.RegistryRepository = mockRegistryRepository
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.ImageStore = mockImageStore
c.tx = mockTx
c.AuditService = mockAuditService
c.UpstreamProxyStore = mockUpstreamProxyStore
},
request: api.DeleteRegistryRequestObject{
RegistryRef: "reg",
},
expectedResp: api.DeleteRegistry200JSONResponse{
SuccessJSONResponse: api.SuccessJSONResponse{
Status: api.StatusSUCCESS,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Setup
controller := &APIController{}
tt.setupMocks(controller)
// Execute with the mock session context
resp, err := controller.DeleteRegistry(testCtx, tt.request)
// Verify error only if explicitly expected.
if tt.expectedError != nil {
assert.Error(t, err, "Expected an error but got none")
assert.Equal(t, tt.expectedError.Error(), err.Error(), "Error message should match")
} else if _, ok := tt.expectedResp.(api.DeleteRegistry200JSONResponse); ok {
// Only assert no error for success responses.
assert.NoError(t, err, "Expected no error for success response")
}
// For error response types like 400/404/403, we don't assert err since the response object is what matters.
// Verify response with detailed assertions.
assert.NotNil(t, resp, "Response should not be nil")
// Verify correct response type matching.
switch tt.expectedResp.(type) {
case api.DeleteRegistry200JSONResponse:
_, ok := resp.(api.DeleteRegistry200JSONResponse)
assert.True(t, ok, "Expected 200 success response")
// Not checking Status field as it's hardcoded in test data and doesn't validate behavior.
case api.DeleteRegistry400JSONResponse:
_, ok := resp.(api.DeleteRegistry400JSONResponse)
assert.True(t, ok, "Expected 400 bad request response")
// Not checking fields as they're hardcoded in test data.
case api.DeleteRegistry403JSONResponse:
_, ok := resp.(api.DeleteRegistry403JSONResponse)
assert.True(t, ok, "Expected 403 forbidden response")
// Not checking fields as they're hardcoded in test data.
case api.DeleteRegistry404JSONResponse:
_, ok := resp.(api.DeleteRegistry404JSONResponse)
assert.True(t, ok, "Expected 404 not found response")
// Not checking fields as they're hardcoded in test data.
default:
// Fallback to simple type equality for any other response types.
expectedType := fmt.Sprintf("%T", tt.expectedResp)
actualType := fmt.Sprintf("%T", resp)
assert.Equal(t, expectedType, actualType, "Response type should match.")
}
// Verify only essential mocks since we're not executing transaction functions.
if controller.SpaceFinder != nil {
mockSpaceFinder, ok := controller.SpaceFinder.(*mocks.SpaceFinder)
if !ok {
t.Fatal("Expected SpaceFinder to be of type *mocks.SpaceFinder")
}
mockSpaceFinder.AssertExpectations(t)
}
// Verify only FindByRef and GetPermissionChecks from RegistryRepository.
if controller.RegistryRepository != nil {
mockRegistryRepo, ok := controller.RegistryRepository.(*mocks.RegistryRepository)
if !ok {
t.Fatal("Expected RegistryRepository to be of type *mocks.RegistryRepository")
}
// We could use AssertCalled for specific methods if needed.
// Only verify GetByParentIDAndName which is called before the transaction.
mockRegistryRepo.AssertCalled(t, "GetByParentIDAndName", mock.Anything, mock.Anything, mock.Anything)
}
if controller.Authorizer != nil {
mockAuthorizer, ok := controller.Authorizer.(*mocks.Authorizer)
if !ok {
t.Fatal("Expected Authorizer to be of type *mocks.Authorizer")
}
mockAuthorizer.AssertExpectations(t)
}
if controller.RegistryMetadataHelper != nil {
mockRegistryMetadataHelper, ok := controller.RegistryMetadataHelper.(*mocks.RegistryMetadataHelper)
if !ok {
t.Fatal("Expected RegistryMetadataHelper to be of type *mocks.RegistryMetadataHelper")
}
mockRegistryMetadataHelper.AssertExpectations(t)
}
// Verify transaction was attempted.
if controller.tx != nil {
mockTx, ok := controller.tx.(*mocks.Transaction)
if !ok {
t.Fatal("Expected tx to be of type *mocks.Transaction")
}
mockTx.AssertCalled(t, "WithTx", mock.Anything, mock.Anything)
}
})
}
}

View File

@ -67,7 +67,7 @@ func (c *APIController) GetArtifactDetails(
image := string(r.Artifact)
version := string(r.Version)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return artifact.GetArtifactDetails500JSONResponse{

View File

@ -69,7 +69,7 @@ func (c *APIController) GetArtifactFiles(
image := string(r.Artifact)
version := string(r.Version)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, reqInfo.parentID, reqInfo.RegistryIdentifier)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, reqInfo.ParentID, reqInfo.RegistryIdentifier)
if err != nil {
return artifact.GetArtifactFiles500JSONResponse{

View File

@ -76,11 +76,11 @@ func (c *APIController) GetAllArtifacts(
latestVersion = bool(*r.Params.LatestVersion)
}
artifacts, err := c.TagStore.GetAllArtifactsByParentID(
ctx, regInfo.parentID, &regInfo.registryIDs,
ctx, regInfo.ParentID, &regInfo.registryIDs,
regInfo.sortByField, regInfo.sortByOrder, regInfo.limit, regInfo.offset, regInfo.searchTerm,
latestVersion, regInfo.packageTypes)
count, _ := c.TagStore.CountAllArtifactsByParentID(
ctx, regInfo.parentID, &regInfo.registryIDs,
ctx, regInfo.ParentID, &regInfo.registryIDs,
regInfo.searchTerm, latestVersion, regInfo.packageTypes)
if err != nil {
return artifact.GetAllArtifacts500JSONResponse{

View File

@ -72,7 +72,7 @@ func (c *APIController) GetDockerArtifactDetails(
version := string(r.Version)
manifestDigest := string(r.Params.Digest)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return artifact.GetDockerArtifactDetails500JSONResponse{

View File

@ -81,7 +81,7 @@ func (c *APIController) GetDockerArtifactLayers(
if err != nil {
return getLayersErrorResponse(ctx, err)
}
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return getLayersErrorResponse(ctx, err)
}

View File

@ -74,7 +74,7 @@ func (c *APIController) GetDockerArtifactManifest(
manifestPayload, err := c.ManifestStore.GetManifestPayload(
ctx,
regInfo.parentID,
regInfo.ParentID,
regInfo.RegistryIdentifier,
imageName,
manifestDigest,

View File

@ -92,10 +92,9 @@ func (c *APIController) GetDockerArtifactManifests(
}, nil
}
func (c *APIController) getManifestList(
ctx context.Context, reqManifest *ml.DeserializedManifestList, registry *types.Registry, image string,
regInfo *RegistryRequestBaseInfo,
) ([]artifact.DockerManifestDetails, error) {
func (c *APIController) getManifestList(ctx context.Context, reqManifest *ml.DeserializedManifestList,
registry *types.Registry, image string, regInfo *types.RegistryRequestBaseInfo) (
[]artifact.DockerManifestDetails, error) {
manifestDetailsList := []artifact.DockerManifestDetails{}
for _, manifestEntry := range reqManifest.Manifests {
dgst, err := types.NewDigest(manifestEntry.Digest)
@ -169,10 +168,10 @@ func (c *APIController) getManifestDetails(
// of Docker manifest details.
func (c *APIController) ProcessManifest(
ctx context.Context,
regInfo *RegistryRequestBaseInfo,
regInfo *types.RegistryRequestBaseInfo,
image, version string,
) ([]artifact.DockerManifestDetails, error) {
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return nil, err
}

View File

@ -67,7 +67,7 @@ func (c *APIController) GetHelmArtifactDetails(
image := string(r.Artifact)
version := string(r.Version)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
registry, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return artifact.GetHelmArtifactDetails500JSONResponse{

View File

@ -65,7 +65,7 @@ func (c *APIController) GetHelmArtifactManifest(
manifestPayload, err := c.ManifestStore.FindManifestPayloadByTagName(
ctx,
regInfo.parentID,
regInfo.ParentID,
regInfo.RegistryIdentifier,
imageName,
version,

View File

@ -77,11 +77,11 @@ func (c *APIController) ListArtifactLabels(
}
labels, err := c.ImageStore.GetLabelsByParentIDAndRepo(
ctx, regInfo.parentID,
ctx, regInfo.ParentID,
regInfo.RegistryIdentifier, regInfo.limit, regInfo.offset, regInfo.searchTerm,
)
count, _ := c.ImageStore.CountLabelsByParentIDAndRepo(
ctx, regInfo.parentID,
ctx, regInfo.ParentID,
regInfo.RegistryIdentifier, regInfo.searchTerm,
)

View File

@ -80,14 +80,14 @@ func (c *APIController) FetchArtifactSummary(
}
if registry.PackageType == artifact.PackageTypeDOCKER || registry.PackageType == artifact.PackageTypeHELM {
tag, err := c.TagStore.GetTagMetadata(ctx, regInfo.parentID, regInfo.RegistryIdentifier, image, version)
tag, err := c.TagStore.GetTagMetadata(ctx, regInfo.ParentID, regInfo.RegistryIdentifier, image, version)
if err != nil {
return "", "", "", err
}
return image, tag.Name, tag.PackageType, nil
}
artifact, err := c.ArtifactStore.GetArtifactMetadata(ctx, regInfo.parentID,
artifact, err := c.ArtifactStore.GetArtifactMetadata(ctx, regInfo.ParentID,
regInfo.RegistryIdentifier, image, version)
if err != nil {

View File

@ -89,7 +89,7 @@ func (c *APIController) GetAllArtifactVersions(
//nolint:nestif
if registry.PackageType == artifact.PackageTypeDOCKER || registry.PackageType == artifact.PackageTypeHELM {
tags, err := c.TagStore.GetAllTagsByRepoAndImage(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
image, regInfo.sortByField, regInfo.sortByOrder, regInfo.limit, regInfo.offset, regInfo.searchTerm,
)
if err != nil {
@ -114,7 +114,7 @@ func (c *APIController) GetAllArtifactVersions(
}
}
count, err := c.TagStore.CountAllTagsByRepoAndImage(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
image, regInfo.searchTerm,
)
@ -134,7 +134,7 @@ func (c *APIController) GetAllArtifactVersions(
}, nil
}
metadata, err := c.ArtifactStore.GetAllVersionsByRepoAndImage(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
image, regInfo.sortByField, regInfo.sortByOrder, regInfo.limit, regInfo.offset, regInfo.searchTerm,
)
if err != nil {
@ -142,7 +142,7 @@ func (c *APIController) GetAllArtifactVersions(
}
cnt, _ := c.ArtifactStore.CountAllVersionsByRepoAndImage(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
image, regInfo.searchTerm,
)
@ -164,6 +164,7 @@ func setDigestCount(ctx context.Context, tags []types.TagMetadata) error {
return nil
}
//nolint:unused // kept for potential future use
func setDigestCountInTagMetadata(ctx context.Context, t *types.TagMetadata) error {
m := types.Manifest{
SchemaVersion: t.SchemaVersion,
@ -188,6 +189,7 @@ func setDigestCountInTagMetadata(ctx context.Context, t *types.TagMetadata) erro
return nil
}
//nolint:unused,unparam // kept for potential future use
func throw500Error(err error) (artifact.GetAllArtifactVersionsResponseObject, error) {
wrappedErr := fmt.Errorf("internal server error: %w", err)
return artifact.GetAllArtifactVersions500JSONResponse{

View File

@ -25,6 +25,7 @@ import (
"github.com/harness/gitness/app/paths"
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/common"
"github.com/harness/gitness/registry/utils"
"github.com/harness/gitness/types/enum"
"github.com/rs/zerolog/log"
@ -65,7 +66,7 @@ func (c *APIController) GetClientSetupDetails(
}, nil
}
reg, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
reg, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return artifact.GetClientSetupDetails404JSONResponse{
NotFoundJSONResponse: artifact.NotFoundJSONResponse(
@ -454,6 +455,7 @@ func (c *APIController) generateHelmClientSetupDetail(
}
}
// TODO: Remove StringPtr / see why it is used.
func (c *APIController) generateMavenClientSetupDetail(
ctx context.Context,
artifactName *artifact.ArtifactParam,
@ -466,62 +468,62 @@ func (c *APIController) generateMavenClientSetupDetail(
generateTokenStepType := artifact.ClientSetupStepTypeGenerateToken
section1 := artifact.ClientSetupSection{
Header: stringPtr("1. Generate Identity Token"),
SecHeader: stringPtr("An identity token will serve as the password for uploading and downloading artifacts."),
Header: utils.StringPtr("1. Generate Identity Token"),
SecHeader: utils.StringPtr("An identity token will serve as the password for uploading and downloading artifacts."),
}
_ = section1.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Generate an identity token"),
Header: utils.StringPtr("Generate an identity token"),
Type: &generateTokenStepType,
},
},
})
mavenSection1 := artifact.ClientSetupSection{
Header: stringPtr("2. Pull a Maven Package"),
SecHeader: stringPtr("Set default repository in your pom.xml file."),
Header: utils.StringPtr("2. Pull a Maven Package"),
SecHeader: utils.StringPtr("Set default repository in your pom.xml file."),
}
_ = mavenSection1.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("To set default registry in your pom.xml file by adding the following:"),
Header: utils.StringPtr("To set default registry in your pom.xml file by adding the following:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("<repositories>\n <repository>\n <id>maven-dev</id>\n <url><REGISTRY_URL>/<REGISTRY_NAME></url>\n <releases>\n <enabled>true</enabled>\n <updatePolicy>always</updatePolicy>\n </releases>\n <snapshots>\n <enabled>true</enabled>\n <updatePolicy>always</updatePolicy>\n </snapshots>\n </repository>\n</repositories>"),
Value: utils.StringPtr("<repositories>\n <repository>\n <id>maven-dev</id>\n <url><REGISTRY_URL>/<REGISTRY_NAME></url>\n <releases>\n <enabled>true</enabled>\n <updatePolicy>always</updatePolicy>\n </releases>\n <snapshots>\n <enabled>true</enabled>\n <updatePolicy>always</updatePolicy>\n </snapshots>\n </repository>\n</repositories>"),
},
},
},
{
//nolint:lll
Header: stringPtr("Copy the following your ~/ .m2/settings.xml file for MacOs, or $USERPROFILE$\\ .m2\\settings.xml for Windows to authenticate with token to pull from your Maven registry."),
Header: utils.StringPtr("Copy the following your ~/ .m2/settings.xml file for MacOs, or $USERPROFILE$\\ .m2\\settings.xml for Windows to authenticate with token to pull from your Maven registry."),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("<settings>\n <servers>\n <server>\n <id>maven-dev</id>\n <username><USERNAME></username>\n <password>identity-token</password>\n </server>\n </servers>\n</settings>"),
Value: utils.StringPtr("<settings>\n <servers>\n <server>\n <id>maven-dev</id>\n <username><USERNAME></username>\n <password>identity-token</password>\n </server>\n </servers>\n</settings>"),
},
},
},
{
//nolint:lll
Header: stringPtr("Add a dependency to the project's pom.xml (replace <GROUP_ID>, <ARTIFACT_ID> & <VERSION> with your own):"),
Header: utils.StringPtr("Add a dependency to the project's pom.xml (replace <GROUP_ID>, <ARTIFACT_ID> & <VERSION> with your own):"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("<dependency>\n <groupId><GROUP_ID></groupId>\n <artifactId><ARTIFACT_ID></artifactId>\n <version><VERSION></version>\n</dependency>"),
Value: utils.StringPtr("<dependency>\n <groupId><GROUP_ID></groupId>\n <artifactId><ARTIFACT_ID></artifactId>\n <version><VERSION></version>\n</dependency>"),
},
},
},
{
Header: stringPtr("Install dependencies in pom.xml file"),
Header: utils.StringPtr("Install dependencies in pom.xml file"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("mvn install"),
Value: utils.StringPtr("mvn install"),
},
},
},
@ -529,39 +531,39 @@ func (c *APIController) generateMavenClientSetupDetail(
})
mavenSection2 := artifact.ClientSetupSection{
Header: stringPtr("3. Push a Maven Package"),
SecHeader: stringPtr("Set default repository in your pom.xml file."),
Header: utils.StringPtr("3. Push a Maven Package"),
SecHeader: utils.StringPtr("Set default repository in your pom.xml file."),
}
_ = mavenSection2.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("To set default registry in your pom.xml file by adding the following:"),
Header: utils.StringPtr("To set default registry in your pom.xml file by adding the following:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("<distributionManagement>\n <snapshotRepository>\n <id>maven-dev</id>\n <url><REGISTRY_URL>/<REGISTRY_NAME></url>\n </snapshotRepository>\n <repository>\n <id>maven-dev</id>\n <url><REGISTRY_URL>/<REGISTRY_NAME></url>\n </repository>\n</distributionManagement>"),
Value: utils.StringPtr("<distributionManagement>\n <snapshotRepository>\n <id>maven-dev</id>\n <url><REGISTRY_URL>/<REGISTRY_NAME></url>\n </snapshotRepository>\n <repository>\n <id>maven-dev</id>\n <url><REGISTRY_URL>/<REGISTRY_NAME></url>\n </repository>\n</distributionManagement>"),
},
},
},
{
//nolint:lll
Header: stringPtr("Copy the following your ~/ .m2/setting.xml file for MacOs, or $USERPROFILE$\\ .m2\\settings.xml for Windows to authenticate with token to push to your Maven registry."),
Header: utils.StringPtr("Copy the following your ~/ .m2/setting.xml file for MacOs, or $USERPROFILE$\\ .m2\\settings.xml for Windows to authenticate with token to push to your Maven registry."),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("<settings>\n <servers>\n <server>\n <id>maven-dev</id>\n <username><USERNAME></username>\n <password>identity-token</password>\n </server>\n </servers>\n</settings>"),
Value: utils.StringPtr("<settings>\n <servers>\n <server>\n <id>maven-dev</id>\n <username><USERNAME></username>\n <password>identity-token</password>\n </server>\n </servers>\n</settings>"),
},
},
},
{
Header: stringPtr("Publish package to your Maven registry."),
Header: utils.StringPtr("Publish package to your Maven registry."),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("mvn deploy"),
Value: utils.StringPtr("mvn deploy"),
},
},
},
@ -569,46 +571,46 @@ func (c *APIController) generateMavenClientSetupDetail(
})
gradleSection1 := artifact.ClientSetupSection{
Header: stringPtr("2. Pull a Gradle Package"),
SecHeader: stringPtr("Set default repository in your build.gradle file."),
Header: utils.StringPtr("2. Pull a Gradle Package"),
SecHeader: utils.StringPtr("Set default repository in your build.gradle file."),
}
_ = gradleSection1.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Set the default registry in your projects build.gradle by adding the following:"),
Header: utils.StringPtr("Set the default registry in your projects build.gradle by adding the following:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("repositories{\n maven{\n url \"<REGISTRY_URL>/<REGISTRY_NAME>\"\n\n credentials {\n username \"<USERNAME>\"\n password \"identity-token\"\n }\n }\n}"),
Value: utils.StringPtr("repositories{\n maven{\n url \"<REGISTRY_URL>/<REGISTRY_NAME>\"\n\n credentials {\n username \"<USERNAME>\"\n password \"identity-token\"\n }\n }\n}"),
},
},
},
{
//nolint:lll
Header: stringPtr("As this is a private registry, youll need to authenticate. Create or add to the ~/.gradle/gradle.properties file with the following:"),
Header: utils.StringPtr("As this is a private registry, youll need to authenticate. Create or add to the ~/.gradle/gradle.properties file with the following:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("repositoryUser=<USERNAME>\nrepositoryPassword={{identity-token}}"),
Value: utils.StringPtr("repositoryUser=<USERNAME>\nrepositoryPassword={{identity-token}}"),
},
},
},
{
Header: stringPtr("Add a dependency to the projects build.gradle"),
Header: utils.StringPtr("Add a dependency to the projects build.gradle"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("dependencies {\n implementation '<GROUP_ID>:<ARTIFACT_ID>:<VERSION>'\n}"),
Value: utils.StringPtr("dependencies {\n implementation '<GROUP_ID>:<ARTIFACT_ID>:<VERSION>'\n}"),
},
},
},
{
Header: stringPtr("Install dependencies in build.gradle file"),
Header: utils.StringPtr("Install dependencies in build.gradle file"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("gradlew build // Linux or OSX\n gradlew.bat build // Windows"),
Value: utils.StringPtr("gradlew build // Linux or OSX\n gradlew.bat build // Windows"),
},
},
},
@ -616,28 +618,28 @@ func (c *APIController) generateMavenClientSetupDetail(
})
gradleSection2 := artifact.ClientSetupSection{
Header: stringPtr("3. Push a Gradle Package"),
SecHeader: stringPtr("Set default repository in your build.gradle file."),
Header: utils.StringPtr("3. Push a Gradle Package"),
SecHeader: utils.StringPtr("Set default repository in your build.gradle file."),
}
_ = gradleSection2.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Add a maven publish plugin configuration to the project's build.gradle."),
Header: utils.StringPtr("Add a maven publish plugin configuration to the project's build.gradle."),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("publishing {\n publications {\n maven(MavenPublication) {\n groupId = 'GROUP_ID'\n artifactId = 'ARTIFACT_ID'\n version = 'VERSION'\n\n from components.java\n }\n }\n}"),
Value: utils.StringPtr("publishing {\n publications {\n maven(MavenPublication) {\n groupId = 'GROUP_ID'\n artifactId = 'ARTIFACT_ID'\n version = 'VERSION'\n\n from components.java\n }\n }\n}"),
},
},
},
{
Header: stringPtr("Publish package to your Maven registry."),
Header: utils.StringPtr("Publish package to your Maven registry."),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("gradlew publish"),
Value: utils.StringPtr("gradlew publish"),
},
},
},
@ -645,47 +647,47 @@ func (c *APIController) generateMavenClientSetupDetail(
})
sbtSection1 := artifact.ClientSetupSection{
Header: stringPtr("2. Pull a Sbt/Scala Package"),
SecHeader: stringPtr("Set default repository in your build.sbt file."),
Header: utils.StringPtr("2. Pull a Sbt/Scala Package"),
SecHeader: utils.StringPtr("Set default repository in your build.sbt file."),
}
_ = sbtSection1.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Set the default registry in your projects build.sbt by adding the following:"),
Header: utils.StringPtr("Set the default registry in your projects build.sbt by adding the following:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("resolver += \"Harness Registry\" at \"<REGISTRY_URL>/<REGISTRY_NAME>\"\ncredentials += Credentials(Path.userHome / \".sbt\" / \".Credentials\")"),
Value: utils.StringPtr("resolver += \"Harness Registry\" at \"<REGISTRY_URL>/<REGISTRY_NAME>\"\ncredentials += Credentials(Path.userHome / \".sbt\" / \".Credentials\")"),
},
},
},
{
//nolint:lll
Header: stringPtr("As this is a private registry, youll need to authenticate. Create or add to the ~/.sbt/.credentials file with the following:"),
Header: utils.StringPtr("As this is a private registry, youll need to authenticate. Create or add to the ~/.sbt/.credentials file with the following:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: stringPtr("realm=Harness Registry\nhost=<LOGIN_HOSTNAME>\nuser=<USERNAME>\npassword={{identity-token}}"),
Value: utils.StringPtr("realm=Harness Registry\nhost=<LOGIN_HOSTNAME>\nuser=<USERNAME>\npassword={{identity-token}}"),
},
},
},
{
Header: stringPtr("Add a dependency to the projects build.sbt"),
Header: utils.StringPtr("Add a dependency to the projects build.sbt"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("libraryDependencies += \"<GROUP_ID>\" % \"<ARTIFACT_ID>\" % \"<VERSION>\""),
Value: utils.StringPtr("libraryDependencies += \"<GROUP_ID>\" % \"<ARTIFACT_ID>\" % \"<VERSION>\""),
},
},
},
{
Header: stringPtr("Install dependencies in build.sbt file"),
Header: utils.StringPtr("Install dependencies in build.sbt file"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("sbt update"),
Value: utils.StringPtr("sbt update"),
},
},
},
@ -693,27 +695,27 @@ func (c *APIController) generateMavenClientSetupDetail(
})
sbtSection2 := artifact.ClientSetupSection{
Header: stringPtr("3. Push a Sbt/Scala Package"),
SecHeader: stringPtr("Set default repository in your build.sbt file."),
Header: utils.StringPtr("3. Push a Sbt/Scala Package"),
SecHeader: utils.StringPtr("Set default repository in your build.sbt file."),
}
_ = sbtSection2.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Add publish configuration to the projects build.sbt."),
Header: utils.StringPtr("Add publish configuration to the projects build.sbt."),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("publishTo := Some(\"Harness Registry\" at \"<REGISTRY_URL>/<REGISTRY_NAME>\")"),
Value: utils.StringPtr("publishTo := Some(\"Harness Registry\" at \"<REGISTRY_URL>/<REGISTRY_NAME>\")"),
},
},
},
{
Header: stringPtr("Publish package to your Maven registry."),
Header: utils.StringPtr("Publish package to your Maven registry."),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("sbt publish"),
Value: utils.StringPtr("sbt publish"),
},
},
},
@ -724,19 +726,19 @@ func (c *APIController) generateMavenClientSetupDetail(
config := artifact.TabSetupStepConfig{
Tabs: &[]artifact.TabSetupStep{
{
Header: stringPtr("Maven"),
Header: utils.StringPtr("Maven"),
Sections: &[]artifact.ClientSetupSection{
mavenSection1,
},
},
{
Header: stringPtr("Gradle"),
Header: utils.StringPtr("Gradle"),
Sections: &[]artifact.ClientSetupSection{
gradleSection1,
},
},
{
Header: stringPtr("Sbt/Scala"),
Header: utils.StringPtr("Sbt/Scala"),
Sections: &[]artifact.ClientSetupSection{
sbtSection1,
},
@ -794,16 +796,16 @@ func (c *APIController) generatePythonClientSetupDetail(
// Authentication section
section1 := artifact.ClientSetupSection{
Header: stringPtr("Configure Authentication"),
Header: utils.StringPtr("Configure Authentication"),
}
_ = section1.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Create or update your ~/.pypirc file with the following content:"),
Header: utils.StringPtr("Create or update your ~/.pypirc file with the following content:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("[distutils]\n" +
Value: utils.StringPtr("[distutils]\n" +
"index-servers = harness\n\n" +
"[harness]\n" +
"repository = <REGISTRY_URL>\n" +
@ -813,7 +815,7 @@ func (c *APIController) generatePythonClientSetupDetail(
},
},
{
Header: stringPtr("Generate an identity token for authentication"),
Header: utils.StringPtr("Generate an identity token for authentication"),
Type: &generateTokenType,
},
},
@ -821,19 +823,19 @@ func (c *APIController) generatePythonClientSetupDetail(
// Publish section
section2 := artifact.ClientSetupSection{
Header: stringPtr("Publish Package"),
Header: utils.StringPtr("Publish Package"),
}
_ = section2.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Build and publish your package:"),
Header: utils.StringPtr("Build and publish your package:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("python -m build"),
Value: utils.StringPtr("python -m build"),
},
{
Value: stringPtr("python -m twine upload --repository harness /path/to/files/*"),
Value: utils.StringPtr("python -m twine upload --repository harness /path/to/files/*"),
},
},
},
@ -842,16 +844,16 @@ func (c *APIController) generatePythonClientSetupDetail(
// Install section
section3 := artifact.ClientSetupSection{
Header: stringPtr("Install Package"),
Header: utils.StringPtr("Install Package"),
}
_ = section3.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Install a package using pip:"),
Header: utils.StringPtr("Install a package using pip:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("pip install --index-url <UPLOAD_URL>/simple --no-deps <ARTIFACT_NAME>==<VERSION>"),
Value: utils.StringPtr("pip install --index-url <UPLOAD_URL>/simple --no-deps <ARTIFACT_NAME>==<VERSION>"),
},
},
},
@ -901,24 +903,24 @@ func (c *APIController) generateNpmClientSetupDetail(
// Authentication section
section1 := artifact.ClientSetupSection{
Header: stringPtr("Configure Authentication"),
Header: utils.StringPtr("Configure Authentication"),
}
_ = section1.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Create or update your ~/.npmrc file with the following content:"),
Header: utils.StringPtr("Create or update your ~/.npmrc file with the following content:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("https:<REGISTRY_URL>/"),
Value: utils.StringPtr("https:<REGISTRY_URL>/"),
},
{
Value: stringPtr("<REGISTRY_URL>/:_authToken <TOKEN>"),
Value: utils.StringPtr("<REGISTRY_URL>/:_authToken <TOKEN>"),
},
},
},
{
Header: stringPtr("Generate an identity token for authentication"),
Header: utils.StringPtr("Generate an identity token for authentication"),
Type: &generateTokenType,
},
},
@ -926,19 +928,19 @@ func (c *APIController) generateNpmClientSetupDetail(
// Publish section
section2 := artifact.ClientSetupSection{
Header: stringPtr("Publish Package"),
Header: utils.StringPtr("Publish Package"),
}
_ = section2.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Build and publish your package:"),
Header: utils.StringPtr("Build and publish your package:"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("npm init -y\n"),
Value: utils.StringPtr("npm run build\n"),
},
{
Value: stringPtr("npm publish"),
Value: utils.StringPtr("npm publish"),
},
},
},
@ -947,16 +949,16 @@ func (c *APIController) generateNpmClientSetupDetail(
// Install section
section3 := artifact.ClientSetupSection{
Header: stringPtr("Install Package"),
Header: utils.StringPtr("Install Package"),
}
_ = section3.FromClientSetupStepConfig(artifact.ClientSetupStepConfig{
Steps: &[]artifact.ClientSetupStep{
{
Header: stringPtr("Install a package using npm"),
Header: utils.StringPtr("Install a package using npm"),
Type: &staticStepType,
Commands: &[]artifact.ClientSetupStepCommand{
{
Value: stringPtr("npm install <ARTIFACT_NAME>@<VERSION>"),
Value: utils.StringPtr("npm install <ARTIFACT_NAME>@<VERSION>"),
},
},
},
@ -1078,44 +1080,40 @@ func replaceText(
uploadURL string,
) {
if username != "" {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<USERNAME>", username))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<USERNAME>", username))
if (*st.Commands)[i].Label != nil {
(*st.Commands)[i].Label = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Label, "<USERNAME>", username))
(*st.Commands)[i].Label = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Label, "<USERNAME>", username))
}
}
if groupID != "" {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<GROUP_ID>", groupID))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<GROUP_ID>", groupID))
}
if registryURL != "" {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<REGISTRY_URL>", registryURL))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<REGISTRY_URL>", registryURL))
}
if uploadURL != "" {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<UPLOAD_URL>", uploadURL))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<UPLOAD_URL>", uploadURL))
}
if hostname != "" {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<HOSTNAME>", hostname))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<HOSTNAME>", hostname))
}
if hostname != "" {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value,
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value,
"<LOGIN_HOSTNAME>", common.GetHost(hostname)))
}
if repoName != "" {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<REGISTRY_NAME>", repoName))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<REGISTRY_NAME>", repoName))
}
if image != nil {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<IMAGE_NAME>",
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<IMAGE_NAME>",
string(*image)))
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<ARTIFACT_ID>",
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<ARTIFACT_ID>",
string(*image)))
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<ARTIFACT_NAME>",
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<ARTIFACT_NAME>",
string(*image)))
}
if tag != nil {
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<TAG>", string(*tag)))
(*st.Commands)[i].Value = stringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<VERSION>", string(*tag)))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<TAG>", string(*tag)))
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<VERSION>", string(*tag)))
}
}
func stringPtr(s string) *string {
return &s
}

View File

@ -96,7 +96,7 @@ func (c *APIController) GetAllRegistries(
var count int64
repos, err = c.RegistryRepository.GetAll(
ctx,
regInfo.parentID,
regInfo.ParentID,
regInfo.packageTypes,
regInfo.sortByField,
regInfo.sortByOrder,
@ -108,7 +108,7 @@ func (c *APIController) GetAllRegistries(
)
count, _ = c.RegistryRepository.CountAll(
ctx,
regInfo.parentID,
regInfo.ParentID,
regInfo.packageTypes,
regInfo.searchTerm,
repoType,

View File

@ -60,7 +60,7 @@ func (c *APIController) GetRegistry(
),
}, nil
}
repoEntity, _ := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
repoEntity, _ := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if string(repoEntity.Type) == string(artifact.RegistryTypeVIRTUAL) {
cleanupPolicies, err := c.CleanupPolicyStore.GetByRegistryID(ctx, repoEntity.ID)
if err != nil {
@ -84,7 +84,7 @@ func (c *APIController) GetRegistry(
}
upstreamproxyEntity, err := c.UpstreamProxyStore.GetByRegistryIdentifier(
ctx,
regInfo.parentID, regInfo.RegistryIdentifier,
regInfo.ParentID, regInfo.RegistryIdentifier,
)
if len(upstreamproxyEntity.RepoKey) == 0 {
return artifact.GetRegistry404JSONResponse{

View File

@ -85,11 +85,11 @@ func (c *APIController) GetAllArtifactsByRegistry(
var count int64
if registry.PackageType == artifact.PackageTypeDOCKER || registry.PackageType == artifact.PackageTypeHELM {
artifacts, err = c.TagStore.GetAllArtifactsByRepo(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
regInfo.sortByField, regInfo.sortByOrder, regInfo.limit, regInfo.offset, regInfo.searchTerm, regInfo.labels,
)
count, _ = c.TagStore.CountAllArtifactsByRepo(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
regInfo.searchTerm, regInfo.labels,
)
if err != nil {
@ -101,10 +101,10 @@ func (c *APIController) GetAllArtifactsByRegistry(
}
} else {
artifacts, err = c.ArtifactStore.GetArtifactsByRepo(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
regInfo.sortByField, regInfo.sortByOrder, regInfo.limit, regInfo.offset, regInfo.searchTerm, regInfo.labels)
count, _ = c.ArtifactStore.CountArtifactsByRepo(
ctx, regInfo.parentID, regInfo.RegistryIdentifier,
ctx, regInfo.ParentID, regInfo.RegistryIdentifier,
regInfo.searchTerm, regInfo.labels)
if err != nil {
return artifact.GetAllArtifactsByRegistry500JSONResponse{

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//nolint:lll
package metadata
import (
@ -20,239 +21,262 @@ import (
"testing"
"time"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/registry/app/api/controller/mocks"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
gitnesstypes "github.com/harness/gitness/types"
"github.com/harness/gitness/registry/types"
coretypes "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,
}
func TestGetWebhookExecution(t *testing.T) {
now := time.Now().Unix()
tests := []struct {
name string
setupMocks func(
*APIController,
*mocks.SpaceFinder,
*mocks.Authorizer,
*mocks.RegistryMetadataHelper,
*mocks.WebhooksRepository,
*mocks.WebhooksExecutionRepository)
request api.GetWebhookExecutionRequestObject
validate func(*testing.T, api.GetWebhookExecutionResponseObject, error)
}{
{
name: "invalid_execution_identifier",
setupMocks: func(c *APIController, mockSpaceFinder *mocks.SpaceFinder, mockAuthorizer *mocks.Authorizer, mockRegistryMetadataHelper *mocks.RegistryMetadataHelper, mockWebhooksRepo *mocks.WebhooksRepository, mockWebhooksExecRepo *mocks.WebhooksExecutionRepository) {
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
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",
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, "reg", enum.PermissionRegistryView).Return([]coretypes.PermissionCheck{})
mockAuthorizer.On("CheckAll", mock.Anything, (*auth.Session)(nil), mock.Anything).Return(true, nil)
c.SpaceFinder = mockSpaceFinder
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.WebhooksRepository = mockWebhooksRepo
c.WebhooksExecutionRepository = mockWebhooksExecRepo
},
request: api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "invalid",
},
validate: func(t *testing.T, response api.GetWebhookExecutionResponseObject, err error) {
assert.NoError(t, err)
assert.NotNil(t, response)
resp, ok := response.(api.GetWebhookExecution400JSONResponse)
assert.True(t, ok, "expected 400 response")
assert.Equal(t, "400", resp.Code)
assert.Equal(t, "invalid webhook execution identifier: invalid, err: strconv.ParseInt: parsing \"invalid\": invalid syntax", resp.Message)
},
},
Response: gitnesstypes.WebhookExecutionResponse{
Body: "{}", Headers: "headers", Status: "200 OK", StatusCode: 200,
{
name: "permission_check_fails",
setupMocks: func(c *APIController, mockSpaceFinder *mocks.SpaceFinder, mockAuthorizer *mocks.Authorizer, mockRegistryMetadataHelper *mocks.RegistryMetadataHelper, mockWebhooksRepo *mocks.WebhooksRepository, mockWebhooksExecRepo *mocks.WebhooksExecutionRepository) {
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, "reg", enum.PermissionRegistryView).Return([]coretypes.PermissionCheck{})
mockAuthorizer.On("CheckAll", mock.Anything, mock.Anything, mock.Anything).Return(false, nil)
c.SpaceFinder = mockSpaceFinder
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.WebhooksRepository = mockWebhooksRepo
c.WebhooksExecutionRepository = mockWebhooksExecRepo
},
request: api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
},
validate: func(t *testing.T, response api.GetWebhookExecutionResponseObject, err error) {
assert.NoError(t, err)
assert.NotNil(t, response)
resp, ok := response.(api.GetWebhookExecution403JSONResponse)
assert.True(t, ok, "expected 403 response")
assert.Equal(t, "403", resp.Code)
assert.Equal(t, "forbidden", resp.Message)
},
},
RetriggerOf: nil,
Retriggerable: true,
WebhookID: 4,
Result: enum.WebhookExecutionResultSuccess,
TriggerType: enum.WebhookTriggerArtifactCreated}, nil)
{
name: "success_case",
setupMocks: func(c *APIController, mockSpaceFinder *mocks.SpaceFinder, mockAuthorizer *mocks.Authorizer, mockRegistryMetadataHelper *mocks.RegistryMetadataHelper, mockWebhooksRepo *mocks.WebhooksRepository, mockWebhooksExecRepo *mocks.WebhooksExecutionRepository) {
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
r := api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
execution := &coretypes.WebhookExecutionCore{
ID: 1,
Created: now,
WebhookID: 1,
Result: enum.WebhookExecutionResultSuccess,
Duration: 0,
Error: "",
Retriggerable: false,
Request: coretypes.WebhookExecutionRequest{
URL: "http://example.com",
Headers: "{}",
Body: "{}",
},
Response: coretypes.WebhookExecutionResponse{
StatusCode: 200,
Status: "OK",
Headers: "{}",
Body: "{}",
},
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, "reg", enum.PermissionRegistryView).Return([]coretypes.PermissionCheck{})
mockAuthorizer.On("CheckAll", mock.Anything, (*auth.Session)(nil)).Return(true, nil)
mockWebhooksExecRepo.On("Find", mock.Anything, int64(1)).Return(execution, nil)
c.SpaceFinder = mockSpaceFinder
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.WebhooksRepository = mockWebhooksRepo
c.WebhooksExecutionRepository = mockWebhooksExecRepo
},
request: api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
},
validate: func(t *testing.T, response api.GetWebhookExecutionResponseObject, err error) {
assert.NoError(t, err)
assert.NotNil(t, response)
resp, ok := response.(api.GetWebhookExecution200JSONResponse)
assert.True(t, ok, "expected 200 response")
assert.Equal(t, api.StatusSUCCESS, resp.Status)
exec := resp.Data
assert.Equal(t, int64(1), *exec.Id)
assert.Equal(t, now, *exec.Created)
assert.Equal(t, int64(1), *exec.WebhookId)
assert.Equal(t, api.WebhookExecResultSUCCESS, *exec.Result)
assert.Equal(t, int64(0), *exec.Duration)
assert.Equal(t, "", *exec.Error)
assert.False(t, *exec.Retriggerable)
assert.Equal(t, "http://example.com", *exec.Request.Url)
assert.Equal(t, "{}", *exec.Request.Headers)
assert.Equal(t, "{}", *exec.Request.Body)
assert.Equal(t, 200, *exec.Response.StatusCode)
assert.Equal(t, "OK", *exec.Response.Status)
assert.Equal(t, "{}", *exec.Response.Headers)
assert.Equal(t, "{}", *exec.Response.Body)
},
},
{
name: "find_execution_error",
setupMocks: func(c *APIController, mockSpaceFinder *mocks.SpaceFinder, mockAuthorizer *mocks.Authorizer, mockRegistryMetadataHelper *mocks.RegistryMetadataHelper, mockWebhooksRepo *mocks.WebhooksRepository, mockWebhooksExecRepo *mocks.WebhooksExecutionRepository) {
space := &coretypes.SpaceCore{ID: 2}
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentID: 2,
ParentRef: "root/parent",
}
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On(
"GetRegistryRequestBaseInfo",
mock.Anything,
"",
"reg",
).Return(regInfo, nil)
mockRegistryMetadataHelper.On(
"GetPermissionChecks",
space,
"reg",
enum.PermissionRegistryView,
).Return([]coretypes.PermissionCheck{})
mockAuthorizer.On("CheckAll", mock.Anything, mock.Anything, mock.Anything).Return(true, nil)
mockWebhooksExecRepo.On(
"Find",
mock.Anything,
int64(1),
).Return(nil, fmt.Errorf("error finding execution"))
c.SpaceFinder = mockSpaceFinder
c.Authorizer = mockAuthorizer
c.RegistryMetadataHelper = mockRegistryMetadataHelper
c.WebhooksRepository = mockWebhooksRepo
c.WebhooksExecutionRepository = mockWebhooksExecRepo
},
request: api.GetWebhookExecutionRequestObject{
RegistryRef: "reg",
WebhookIdentifier: "webhook",
WebhookExecutionId: "1",
},
validate: func(t *testing.T, response api.GetWebhookExecutionResponseObject, err error) {
assert.NoError(t, err)
assert.NotNil(t, response)
resp, ok := response.(api.GetWebhookExecution500JSONResponse)
assert.True(t, ok, "expected 500 response")
assert.Equal(t, "500", resp.Code)
assert.Equal(t, "failed to find webhook execution: error finding execution", resp.Message)
},
},
}
response, err := controller.GetWebhookExecution(ctx, r)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create mocks
mockSpaceFinder := new(mocks.SpaceFinder)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockWebhooksRepo := new(mocks.WebhooksRepository)
mockWebhooksExecRepo := new(mocks.WebhooksExecutionRepository)
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)
// Create controller
controller := &APIController{}
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.NoError(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.GetWebhookExecution403JSONResponse{}, response)
assert.Equal(t, "forbidden", 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.NoError(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.GetWebhookExecution400JSONResponse{}, response)
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.NoError(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.GetWebhookExecution500JSONResponse{}, response)
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)
// Setup mocks
tt.setupMocks(controller, mockSpaceFinder, mockAuthorizer, mockRegistryMetadataHelper, mockWebhooksRepo, mockWebhooksExecRepo)
// Call function
resp, err := controller.GetWebhookExecution(context.Background(), tt.request)
// Validate response
tt.validate(t, resp, err)
// Verify mock expectations
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockRegistryMetadataHelper.AssertExpectations(t)
mockWebhooksRepo.AssertExpectations(t)
mockWebhooksExecRepo.AssertExpectations(t)
})
}
}

View File

@ -1,385 +0,0 @@
// 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) (int64, 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

@ -21,27 +21,28 @@ import (
"github.com/harness/gitness/app/paths"
corestore "github.com/harness/gitness/app/store"
"github.com/harness/gitness/registry/app/api/interfaces"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/pkg/commons"
"github.com/harness/gitness/registry/app/store"
registrytypes "github.com/harness/gitness/registry/types"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
var _ RegistryMetadataHelper = (*GitnessRegistryMetadataHelper)(nil)
var _ RegistryMetadataHelper = (*MockRegistryMetadataHelper)(nil)
var _ interfaces.RegistryMetadataHelper = (*GitnessRegistryMetadataHelper)(nil)
type GitnessRegistryMetadataHelper struct {
spacePathStore corestore.SpacePathStore
spaceFinder SpaceFinder
spaceFinder interfaces.SpaceFinder
registryRepository store.RegistryRepository
}
func NewRegistryMetadataHelper(
spacePathStore corestore.SpacePathStore,
spaceFinder SpaceFinder,
spaceFinder interfaces.SpaceFinder,
registryRepository store.RegistryRepository,
) RegistryMetadataHelper {
) interfaces.RegistryMetadataHelper {
gitnessRegistryMetadataHelper := GitnessRegistryMetadataHelper{
spacePathStore: spacePathStore,
spaceFinder: spaceFinder,
@ -50,7 +51,10 @@ func NewRegistryMetadataHelper(
return &gitnessRegistryMetadataHelper
}
func (r *GitnessRegistryMetadataHelper) getSecretSpaceID(ctx context.Context, secretSpacePath *string) (int64, error) {
func (r *GitnessRegistryMetadataHelper) GetSecretSpaceID(
ctx context.Context,
secretSpacePath *string,
) (int64, error) {
if secretSpacePath == nil {
return -1, fmt.Errorf("secret space path is missing")
}
@ -68,7 +72,7 @@ func (r *GitnessRegistryMetadataHelper) GetRegistryRequestBaseInfo(
ctx context.Context,
parentRef string,
regRef string,
) (*RegistryRequestBaseInfo, error) {
) (*registrytypes.RegistryRequestBaseInfo, error) {
// ---------- CHECKS ------------
if commons.IsEmpty(parentRef) && !commons.IsEmpty(regRef) {
parentRef, _, _ = paths.DisectLeaf(regRef)
@ -94,11 +98,11 @@ func (r *GitnessRegistryMetadataHelper) GetRegistryRequestBaseInfo(
rootIdentifierID := rootSpace.ID
parentID := parentSpace.ID
baseInfo := &RegistryRequestBaseInfo{
baseInfo := registrytypes.RegistryRequestBaseInfo{
ParentRef: parentRef,
parentID: parentID,
ParentID: parentID,
RootIdentifier: rootIdentifier,
rootIdentifierID: rootIdentifierID,
RootIdentifierID: rootIdentifierID,
}
// ---------- REGISTRY ------------
@ -117,7 +121,7 @@ func (r *GitnessRegistryMetadataHelper) GetRegistryRequestBaseInfo(
baseInfo.PackageType = reg.PackageType
}
return baseInfo, nil
return &baseInfo, nil
}
func (r *GitnessRegistryMetadataHelper) GetPermissionChecks(
@ -138,7 +142,7 @@ func (r *GitnessRegistryMetadataHelper) GetPermissionChecks(
func (r *GitnessRegistryMetadataHelper) MapToWebhookCore(
ctx context.Context,
webhookRequest api.WebhookRequest,
regInfo *RegistryRequestBaseInfo,
regInfo *registrytypes.RegistryRequestBaseInfo,
) (*types.WebhookCore, error) {
webhook := &types.WebhookCore{
DisplayName: webhookRequest.Name,
@ -163,7 +167,7 @@ func (r *GitnessRegistryMetadataHelper) MapToWebhookCore(
webhook.SecretIdentifier = *webhookRequest.SecretIdentifier
}
if webhookRequest.SecretSpacePath != nil && len(*webhookRequest.SecretSpacePath) > 0 {
secretSpaceID, err := r.getSecretSpaceID(ctx, webhookRequest.SecretSpacePath)
secretSpaceID, err := r.GetSecretSpaceID(ctx, webhookRequest.SecretSpacePath)
if err != nil {
return nil, err
}

View File

@ -1,4 +1,4 @@
// Copyright 2023 Harness, Inc.
// 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.
@ -12,366 +12,532 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//nolint:lll,revive // revive:disable:unused-parameter
package metadata
import (
"context"
"fmt"
"strconv"
"testing"
"time"
"github.com/harness/gitness/registry/app/api/controller/mocks"
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"
"github.com/stretchr/testify/mock"
)
//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{
// Test data setup.
var (
regInfo = &types.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)
// Helper function to create string pointer.
func stringPtr(s string) *string {
return &s
}
func TestMapToWebhook(t *testing.T) {
tests := []struct {
name string
webhookReq api.WebhookRequest
setupMocks func(*mocks.SpacePathStore)
expectedError string
validate func(*testing.T, *gitnesstypes.WebhookCore, error)
}{
{
name: "success_case",
webhookReq: api.WebhookRequest{
Identifier: "webhook",
Name: "webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: &[]api.Trigger{api.TriggerARTIFACTCREATION, api.TriggerARTIFACTDELETION},
Description: stringPtr("Test webhook"),
ExtraHeaders: &[]api.ExtraHeader{
{Key: "key", Value: "value"},
},
},
validate: func(t *testing.T, webhook *gitnesstypes.WebhookCore, err error) {
assert.NoError(t, err)
assert.NotNil(t, webhook)
assert.Equal(t, "webhook", webhook.Identifier)
assert.Equal(t, "webhook", webhook.DisplayName)
assert.Equal(t, "http://example.com", webhook.URL)
assert.True(t, webhook.Enabled)
assert.False(t, webhook.Insecure)
assert.Equal(t, "Test webhook", webhook.Description)
assert.Len(t, webhook.ExtraHeaders, 1)
assert.Equal(t, "key", webhook.ExtraHeaders[0].Key)
assert.Equal(t, "value", webhook.ExtraHeaders[0].Value)
assert.Len(t, webhook.Triggers, 2)
assert.Equal(t, gitnessenum.WebhookTriggerArtifactCreated, webhook.Triggers[0])
assert.Equal(t, gitnessenum.WebhookTriggerArtifactDeleted, webhook.Triggers[1])
},
},
{
name: "with_secret_space_path",
webhookReq: api.WebhookRequest{
Identifier: "webhook",
Name: "webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: &[]api.Trigger{api.TriggerARTIFACTCREATION},
SecretSpacePath: stringPtr("secret/path"),
},
setupMocks: func(mockSpacePathStore *mocks.SpacePathStore) {
mockSpacePathStore.On("FindByPath", mock.Anything, "secret/path").Return(
&gitnesstypes.SpacePath{Value: "secret/path", SpaceID: 2}, nil)
},
validate: func(t *testing.T, webhook *gitnesstypes.WebhookCore, err error) {
assert.NoError(t, err)
assert.NotNil(t, webhook)
assert.Equal(t, int64(2), webhook.SecretSpaceID)
},
},
{
name: "invalid_secret_space_path",
webhookReq: api.WebhookRequest{
Identifier: "webhook",
Name: "webhook",
Url: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: &[]api.Trigger{api.TriggerARTIFACTCREATION},
SecretSpacePath: stringPtr("secret/path"),
},
setupMocks: func(mockSpacePathStore *mocks.SpacePathStore) {
mockSpacePathStore.On("FindByPath", mock.Anything, "secret/path").Return(nil, fmt.Errorf("not found"))
},
expectedError: "failed to get Space Path: not found",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create mocks
mockSpacePathStore := new(mocks.SpacePathStore)
// Create helper
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
// Setup mocks if provided
if tt.setupMocks != nil {
tt.setupMocks(mockSpacePathStore)
}
// Execute test
webhook, err := helper.MapToWebhookCore(context.Background(), tt.webhookReq, regInfo)
// Validate results
if tt.expectedError != "" {
assert.Error(t, err)
assert.Contains(t, err.Error(), tt.expectedError)
assert.Nil(t, webhook)
} else if tt.validate != nil {
tt.validate(t, webhook, err)
}
// Verify mock expectations
mockSpacePathStore.AssertExpectations(t)
})
}
}
//nolint:lll
func TestMapToWebhook_WithSecretSpacePath(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
mockSpacePathStore := new(mocks.SpacePathStore)
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
helper := NewRegistryMetadataHelper(mockSpacePathStore, mockSpaceFinder, mockRegistryRepository)
secretSpacePath := "secret/path"
webhookRequest := api.WebhookRequest{
Identifier: "webhook",
Name: "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)
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, int64(2), webhook.SecretSpaceID)
mockSpacePathStore.AssertExpectations(t)
}
func TestMapToWebhook_WithInexistentSecretSpacePath(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
}
mockSpacePathStore := new(mocks.SpacePathStore)
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
helper := NewRegistryMetadataHelper(mockSpacePathStore, mockSpaceFinder, mockRegistryRepository)
secretSpacePath := "secret/path"
webhookRequest := api.WebhookRequest{
Identifier: "webhook",
Name: "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"))
mockSpacePathStore.On("FindByPath", ctx, "secret/path").
Return(nil, fmt.Errorf("error finding path"))
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")
assert.Nil(t, webhook)
assert.Equal(t, "failed to get Space Path: error finding path", err.Error())
}
func TestMapToWebhookResponseEntity(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
tests := []struct {
name string
webhook *gitnesstypes.WebhookCore
setupMocks func(*mocks.SpacePathStore, *mocks.SpaceFinder, *mocks.RegistryRepository)
expectedError string
validate func(*testing.T, *api.Webhook, error)
}{
{
name: "success_case",
webhook: &gitnesstypes.WebhookCore{
Type: gitnessenum.WebhookTypeInternal,
Identifier: "webhook",
DisplayName: "webhook",
URL: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: []gitnessenum.WebhookTrigger{gitnessenum.WebhookTriggerArtifactCreated},
Created: time.Now().Unix(),
Updated: time.Now().Unix(),
Description: "Test webhook",
SecretIdentifier: "secret-id",
SecretSpaceID: 1,
ExtraHeaders: []gitnesstypes.ExtraHeader{{Key: "key", Value: "value"}},
LatestExecutionResult: &[]gitnessenum.WebhookExecutionResult{gitnessenum.WebhookExecutionResultSuccess}[0],
},
setupMocks: func(mockSpacePathStore *mocks.SpacePathStore, _ *mocks.SpaceFinder, _ *mocks.RegistryRepository) {
mockSpacePathStore.On("FindPrimaryBySpaceID", mock.Anything, int64(1)).Return(
&gitnesstypes.SpacePath{Value: "secret/path"}, nil)
},
validate: func(t *testing.T, webhook *api.Webhook, err error) {
assert.NoError(t, err, "should not return error")
assert.NotNil(t, webhook, "webhook should not be nil")
// Basic fields
assert.Equal(t, "webhook", webhook.Identifier, "identifier should match")
assert.Equal(t, "webhook", webhook.Name, "name should match")
assert.Equal(t, "http://example.com", webhook.Url, "URL should match")
assert.True(t, webhook.Enabled, "should be enabled")
assert.False(t, webhook.Insecure, "should not be insecure")
assert.Equal(t, "Test webhook", *webhook.Description, "description should match")
assert.True(t, *webhook.Internal, "should be internal")
// Triggers
assert.Len(t, *webhook.Triggers, 1, "should have 1 trigger")
assert.Equal(t, api.TriggerARTIFACTCREATION, (*webhook.Triggers)[0], "trigger should match")
// Secret fields
assert.Equal(t, "secret-id", *webhook.SecretIdentifier, "secret identifier should match")
assert.Equal(t, "secret/path", *webhook.SecretSpacePath, "secret space path should match")
assert.Equal(t, int64(1), *webhook.SecretSpaceId, "secret space ID should match")
// Extra headers
assert.Len(t, *webhook.ExtraHeaders, 1, "should have 1 extra header")
assert.Equal(t, "key", (*webhook.ExtraHeaders)[0].Key, "header key should match")
assert.Equal(t, "value", (*webhook.ExtraHeaders)[0].Value, "header value should match")
// Latest execution result
assert.Equal(t, api.WebhookExecResultSUCCESS, *webhook.LatestExecutionResult, "latest execution result should match")
},
},
{
name: "find_primary_by_space_id_error",
webhook: &gitnesstypes.WebhookCore{
SecretSpaceID: 1,
},
setupMocks: func(mockSpacePathStore *mocks.SpacePathStore, _ *mocks.SpaceFinder, _ *mocks.RegistryRepository) {
mockSpacePathStore.On("FindPrimaryBySpaceID", mock.Anything, int64(1)).Return(nil, fmt.Errorf("error finding primary by space ID"))
},
expectedError: "failed to get secret space path: error finding primary by space ID",
},
}
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,
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create mocks
mockSpacePathStore := new(mocks.SpacePathStore)
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
// Create helper
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
// Setup mocks if provided
if tt.setupMocks != nil {
tt.setupMocks(mockSpacePathStore, mockSpaceFinder, mockRegistryRepository)
}
// Execute test
webhook, err := helper.MapToWebhookResponseEntity(context.Background(), tt.webhook)
// Validate results
if tt.expectedError != "" {
assert.Error(t, err, "should return error")
assert.Contains(t, err.Error(), tt.expectedError, "error message should match")
assert.Nil(t, webhook, "webhook should be nil")
} else if tt.validate != nil {
tt.validate(t, webhook, err)
}
// Verify mock expectations
mockSpacePathStore.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
})
}
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, int64(1), *webhookResponseEntity.SecretSpaceId)
}
//nolint:lll
func TestMapToWebhookResponseEntity_FindPrimaryBySpaceIDError(t *testing.T) {
ctx := context.Background()
mockSpacePathStore := new(MockSpacePathStore)
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
func TestMapToWebhookResponseEntity_FindByPathError(t *testing.T) {
// GIVEN
mockSpacePathStore := new(mocks.SpacePathStore)
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryDao := new(mocks.RegistryRepository)
helper := NewRegistryMetadataHelper(mockSpacePathStore, mockSpaceFinder, mockRegistryDao)
webhook := &gitnesstypes.WebhookCore{
ID: 1,
ParentID: 1,
Type: gitnessenum.WebhookTypeInternal,
Identifier: "webhook",
DisplayName: "webhook",
URL: "http://example.com",
Enabled: true,
Insecure: false,
SecretSpaceID: 1,
Created: 1234567890,
Updated: 1234567890,
}
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", mock.Anything, int64(1)).Return(nil, fmt.Errorf("space not found"))
mockSpacePathStore.On("FindPrimaryBySpaceID", ctx, int64(1)).Return(nil, fmt.Errorf("error finding primary by space ID"))
// WHEN
result, err := helper.MapToWebhookResponseEntity(context.Background(), webhook)
webhookResponseEntity, err := helper.MapToWebhookResponseEntity(ctx, &createdWebhook)
// THEN
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")
assert.Nil(t, result)
mockSpacePathStore.AssertExpectations(t)
}
func TestGetRegistryRequestBaseInfo(t *testing.T) {
tests := []struct {
name string
parentRef string
registryName string
setupMocks func(*mocks.SpacePathStore, *mocks.SpaceFinder, *mocks.RegistryRepository)
expectedError string
validate func(*testing.T, *types.RegistryRequestBaseInfo, error)
}{
{
name: "success_case",
parentRef: "root/parent",
registryName: "reg",
setupMocks: func(_ *mocks.SpacePathStore, mockSpaceFinder *mocks.SpaceFinder, mockRegistryRepository *mocks.RegistryRepository) {
mockSpaceFinder.On("FindByRef", mock.Anything, "root").Return(&gitnesstypes.SpaceCore{ID: 1}, nil)
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(&gitnesstypes.SpaceCore{ID: 2}, nil)
mockRegistryRepository.On("GetByParentIDAndName", mock.Anything, int64(2), "reg").Return(&types.Registry{
ID: 3,
Type: api.RegistryTypeVIRTUAL,
}, nil)
},
validate: func(t *testing.T, baseInfo *types.RegistryRequestBaseInfo, err error) {
assert.NoError(t, err, "should not return error")
assert.NotNil(t, baseInfo, "baseInfo should not be nil")
assert.Equal(t, int64(1), baseInfo.RootIdentifierID, "root ID should match")
assert.Equal(t, int64(2), baseInfo.ParentID, "parent ID should match")
assert.Equal(t, int64(3), baseInfo.RegistryID, "registry ID should match")
assert.Equal(t, api.RegistryTypeVIRTUAL, baseInfo.RegistryType, "registry type should match")
},
},
{
name: "empty_parent_ref",
parentRef: "",
registryName: "reg",
expectedError: "parent reference is required",
},
{
name: "invalid_parent_ref",
parentRef: "/",
registryName: "reg",
expectedError: "invalid parent reference",
},
{
name: "root_space_not_found",
parentRef: "root/parent",
registryName: "reg",
setupMocks: func(_ *mocks.SpacePathStore, mockSpaceFinder *mocks.SpaceFinder, _ *mocks.RegistryRepository) {
mockSpaceFinder.On("FindByRef", mock.Anything, "root").Return(nil, fmt.Errorf("not found"))
},
expectedError: "root space not found",
},
{
name: "parent_space_not_found",
parentRef: "root/parent",
registryName: "reg",
setupMocks: func(_ *mocks.SpacePathStore, mockSpaceFinder *mocks.SpaceFinder, _ *mocks.RegistryRepository) {
mockSpaceFinder.On("FindByRef", mock.Anything, "root").Return(&gitnesstypes.SpaceCore{ID: 1}, nil)
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(nil, fmt.Errorf("not found"))
},
expectedError: "parent space not found",
},
{
name: "registry_not_found",
parentRef: "root/parent",
registryName: "reg",
setupMocks: func(_ *mocks.SpacePathStore, mockSpaceFinder *mocks.SpaceFinder, mockRegistryRepository *mocks.RegistryRepository) {
mockSpaceFinder.On("FindByRef", mock.Anything, "root").Return(&gitnesstypes.SpaceCore{ID: 1}, nil)
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(&gitnesstypes.SpaceCore{ID: 2}, nil)
mockRegistryRepository.On("GetByParentIDAndName", mock.Anything, int64(2), "reg").Return(nil, fmt.Errorf("not found"))
},
expectedError: "registry not found",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create mocks
mockSpacePathStore := new(mocks.SpacePathStore)
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
// Create helper
helper := &GitnessRegistryMetadataHelper{
spacePathStore: mockSpacePathStore,
spaceFinder: mockSpaceFinder,
registryRepository: mockRegistryRepository,
}
// Setup mocks if provided
if tt.setupMocks != nil {
tt.setupMocks(mockSpacePathStore, mockSpaceFinder, mockRegistryRepository)
}
// Execute test
baseInfo, err := helper.GetRegistryRequestBaseInfo(context.Background(), tt.parentRef, tt.registryName)
// Validate results
if tt.expectedError != "" {
assert.Error(t, err, "should return error")
assert.Contains(t, err.Error(), tt.expectedError, "error message should match")
assert.Nil(t, baseInfo, "baseInfo should be nil")
} else if tt.validate != nil {
tt.validate(t, baseInfo, err)
}
// Verify mock expectations
mockSpacePathStore.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
})
}
}
func TestMapToInternalWebhookTriggers(t *testing.T) {
helper := &GitnessRegistryMetadataHelper{}
apiTriggers := []api.Trigger{
api.TriggerARTIFACTCREATION,
api.TriggerARTIFACTDELETION,
tests := []struct {
name string
triggers []api.Trigger
expected []gitnessenum.WebhookTrigger
}{
{
name: "success_case",
triggers: []api.Trigger{
api.TriggerARTIFACTCREATION,
api.TriggerARTIFACTDELETION,
},
expected: []gitnessenum.WebhookTrigger{
gitnessenum.WebhookTriggerArtifactCreated,
gitnessenum.WebhookTriggerArtifactDeleted,
},
},
{
name: "empty_triggers",
triggers: []api.Trigger{},
expected: []gitnessenum.WebhookTrigger{},
},
}
expectedInternalTriggers := []gitnessenum.WebhookTrigger{
gitnessenum.WebhookTriggerArtifactCreated,
gitnessenum.WebhookTriggerArtifactDeleted,
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := helper.MapToInternalWebhookTriggers(tt.triggers)
assert.Equal(t, tt.expected, result, "triggers should match")
})
}
internalTriggers := helper.MapToInternalWebhookTriggers(apiTriggers)
assert.Equal(t, expectedInternalTriggers, internalTriggers)
}
func TestMapToAPIWebhookTriggers(t *testing.T) {
helper := &GitnessRegistryMetadataHelper{}
internalTriggers := []gitnessenum.WebhookTrigger{
gitnessenum.WebhookTriggerArtifactCreated,
gitnessenum.WebhookTriggerArtifactDeleted,
tests := []struct {
name string
triggers []gitnessenum.WebhookTrigger
expected []api.Trigger
}{
{
name: "success_case",
triggers: []gitnessenum.WebhookTrigger{
gitnessenum.WebhookTriggerArtifactCreated,
gitnessenum.WebhookTriggerArtifactDeleted,
},
expected: []api.Trigger{
api.TriggerARTIFACTCREATION,
api.TriggerARTIFACTDELETION,
},
},
{
name: "empty_triggers",
triggers: []gitnessenum.WebhookTrigger{},
expected: []api.Trigger{},
},
}
expectedAPITriggers := []api.Trigger{
api.TriggerARTIFACTCREATION,
api.TriggerARTIFACTDELETION,
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := helper.MapToAPIWebhookTriggers(tt.triggers)
assert.Equal(t, tt.expected, result, "triggers should match")
})
}
apiTriggers := helper.MapToAPIWebhookTriggers(internalTriggers)
assert.Equal(t, expectedAPITriggers, apiTriggers)
}

View File

@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
//nolint:lll
package metadata_test
import (
"context"
@ -21,256 +22,302 @@ import (
"time"
gitnesswebhook "github.com/harness/gitness/app/services/webhook"
"github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/controller/mocks"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
gitnesstypes "github.com/harness/gitness/types"
"github.com/harness/gitness/registry/types"
coretypes "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,
var (
webhookExecution = &coretypes.WebhookExecutionCore{
ID: 1,
Created: time.Now().Unix(),
WebhookID: 1,
Result: enum.WebhookExecutionResultSuccess,
Duration: 100,
Error: "",
Retriggerable: false,
Request: coretypes.WebhookExecutionRequest{
URL: "http://example.com",
Headers: "{}",
Body: "{}",
},
Response: coretypes.WebhookExecutionResponse{
StatusCode: 200,
Status: "OK",
Headers: "{}",
Body: "{}",
},
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)
webhookExecutionEntity = &api.WebhookExecution{
Id: &webhookExecution.ID,
Created: &webhookExecution.Created,
Duration: &webhookExecution.Duration,
RetriggerOf: webhookExecution.RetriggerOf,
Retriggerable: &webhookExecution.Retriggerable,
Error: &webhookExecution.Error,
WebhookId: &webhookExecution.WebhookID,
Request: &api.WebhookExecRequest{
Body: &webhookExecution.Request.Body,
Headers: &webhookExecution.Request.Headers,
Url: &webhookExecution.Request.URL,
},
Response: &api.WebhookExecResponse{
Status: &webhookExecution.Response.Status,
StatusCode: &webhookExecution.Response.StatusCode,
Body: &webhookExecution.Response.Body,
Headers: &webhookExecution.Response.Headers,
},
Result: &[]api.WebhookExecResult{api.WebhookExecResultSUCCESS}[0],
TriggerType: &[]api.Trigger{api.TriggerARTIFACTCREATION}[0],
}
)
func TestReTriggerWebhookExecution(t *testing.T) {
// Create mocks that will be used across all tests
mockSpaceFinder := new(mocks.SpaceFinder)
mockRegistryRepository := new(mocks.RegistryRepository)
mockWebhooksRepository := new(mocks.WebhooksRepository)
mockWebhooksExecutionRepository := new(mocks.WebhooksExecutionRepository)
mockAuthorizer := new(mocks.Authorizer)
mockRegistryMetadataHelper := new(mocks.RegistryMetadataHelper)
mockWebhookService := new(mocks.WebhookService)
tests := []struct {
name string
setupMocks func(*metadata.APIController)
request api.ReTriggerWebhookExecutionRequestObject
expectedResp api.ReTriggerWebhookExecutionResponseObject
expectedError error
}{
{
name: "success_case",
setupMocks: func(_ *metadata.APIController) {
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &coretypes.SpaceCore{ID: 2}
var permissionChecks []coretypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", mock.Anything, mock.Anything, mock.Anything).Return(true, nil)
latestExecutionResult := enum.WebhookExecutionResultSuccess
mockWebhookService.On("ReTriggerWebhookExecution", mock.Anything, int64(1)).Return(&gitnesswebhook.TriggerResult{
Execution: webhookExecution,
Webhook: &coretypes.WebhookCore{
Identifier: "webhook",
DisplayName: "webhook",
URL: "http://example.com",
Enabled: true,
Insecure: false,
Triggers: []enum.WebhookTrigger{enum.WebhookTriggerArtifactCreated},
Created: webhookExecution.Created,
Updated: webhookExecution.Created,
Description: "Test webhook",
SecretSpaceID: 1,
ExtraHeaders: []coretypes.ExtraHeader{{Key: "key", Value: "value"}},
LatestExecutionResult: &latestExecutionResult,
},
TriggerType: enum.WebhookTriggerArtifactCreated,
}, nil)
},
request: api.ReTriggerWebhookExecutionRequestObject{
WebhookIdentifier: "webhook",
RegistryRef: "reg",
WebhookExecutionId: "1",
},
expectedResp: api.ReTriggerWebhookExecution200JSONResponse{
WebhookExecutionResponseJSONResponse: api.WebhookExecutionResponseJSONResponse{
Data: *webhookExecutionEntity,
Status: api.StatusSUCCESS,
},
},
},
{
name: "permission_check_fails",
setupMocks: func(_ *metadata.APIController) {
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &coretypes.SpaceCore{ID: 2}
var permissionChecks []coretypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", mock.Anything, mock.Anything, mock.Anything).Return(false, nil)
},
request: api.ReTriggerWebhookExecutionRequestObject{
WebhookIdentifier: "webhook",
RegistryRef: "reg",
WebhookExecutionId: "1",
},
expectedResp: api.ReTriggerWebhookExecution403JSONResponse{
UnauthorizedJSONResponse: api.UnauthorizedJSONResponse{
Code: "403",
Message: "not authorized",
},
},
},
{
name: "invalid_execution_identifier",
setupMocks: func(_ *metadata.APIController) {
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &coretypes.SpaceCore{ID: 2}
var permissionChecks []coretypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", mock.Anything, mock.Anything, mock.Anything).Return(true, nil)
},
request: api.ReTriggerWebhookExecutionRequestObject{
WebhookIdentifier: "webhook",
RegistryRef: "reg",
WebhookExecutionId: "invalid",
},
expectedResp: api.ReTriggerWebhookExecution400JSONResponse{
BadRequestJSONResponse: api.BadRequestJSONResponse{
Code: "400",
Message: "invalid webhook execution identifier: invalid, err: strconv.ParseInt: parsing \"invalid\": invalid syntax",
},
},
},
{
name: "retrigger_execution_error",
setupMocks: func(_ *metadata.APIController) {
regInfo := &types.RegistryRequestBaseInfo{
RegistryID: 1,
RegistryIdentifier: "reg",
ParentRef: "root/parent",
}
space := &coretypes.SpaceCore{ID: 2}
var permissionChecks []coretypes.PermissionCheck
mockRegistryMetadataHelper.On("GetRegistryRequestBaseInfo", mock.Anything, "", "reg").Return(regInfo, nil)
mockSpaceFinder.On("FindByRef", mock.Anything, "root/parent").Return(space, nil)
mockRegistryMetadataHelper.On("GetPermissionChecks", space, regInfo.RegistryIdentifier, enum.PermissionRegistryEdit).Return(permissionChecks)
mockAuthorizer.On("CheckAll", mock.Anything, mock.Anything, mock.Anything).Return(true, nil)
mockWebhookService.On("ReTriggerWebhookExecution", mock.Anything, int64(1)).Return(nil, fmt.Errorf("error"))
},
request: api.ReTriggerWebhookExecutionRequestObject{
WebhookIdentifier: "webhook",
RegistryRef: "reg",
WebhookExecutionId: "1",
},
expectedResp: api.ReTriggerWebhookExecution500JSONResponse{
InternalServerErrorJSONResponse: api.InternalServerErrorJSONResponse{
Code: "500",
Message: "failed to re-trigger execution: error",
},
},
},
}
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)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Clear mock expectations
mockSpaceFinder.ExpectedCalls = nil
mockRegistryRepository.ExpectedCalls = nil
mockWebhooksRepository.ExpectedCalls = nil
mockWebhooksExecutionRepository.ExpectedCalls = nil
mockAuthorizer.ExpectedCalls = nil
mockRegistryMetadataHelper.ExpectedCalls = nil
mockWebhookService.ExpectedCalls = nil
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.NoError(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ReTriggerWebhookExecution403JSONResponse{}, response)
assert.Equal(t, "forbidden", 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.NoError(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ReTriggerWebhookExecution400JSONResponse{}, response)
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.NoError(t, err)
assert.NotNil(t, response)
assert.IsType(t, api.ReTriggerWebhookExecution500JSONResponse{}, response)
assert.Equal(t, "failed to re-trigger execution: error", response.(api.ReTriggerWebhookExecution500JSONResponse).Message) //nolint:errcheck
mockRegistryMetadataHelper.AssertExpectations(t)
mockSpaceFinder.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
controller := &metadata.APIController{
SpaceFinder: mockSpaceFinder,
RegistryRepository: mockRegistryRepository,
WebhooksRepository: mockWebhooksRepository,
WebhooksExecutionRepository: mockWebhooksExecutionRepository,
Authorizer: mockAuthorizer,
RegistryMetadataHelper: mockRegistryMetadataHelper,
WebhookService: mockWebhookService,
}
// Setup mocks
tt.setupMocks(controller)
resp, err := controller.ReTriggerWebhookExecution(context.Background(), tt.request)
assert.Equal(t, tt.expectedError, err)
assert.NotNil(t, resp, "response should not be nil")
switch tt.name {
case "success_case":
successResp, ok := resp.(api.ReTriggerWebhookExecution200JSONResponse)
assert.True(t, ok, "expected 200 response")
assert.Equal(t, api.StatusSUCCESS, successResp.Status)
assert.NotNil(t, successResp.Data, "Data should not be nil")
assert.NotNil(t, successResp.Data.Id, "Id should not be nil")
assert.NotNil(t, successResp.Data.Error, "Error should not be nil")
assert.NotNil(t, successResp.Data.Request, "Request should not be nil")
assert.NotNil(t, successResp.Data.Response, "Response should not be nil")
assert.NotNil(t, successResp.Data.Result, "Result should not be nil")
assert.NotNil(t, successResp.Data.TriggerType, "TriggerType should not be nil")
if assert.NotNil(t, successResp.Data.Request) {
assert.Equal(t, "{}", *successResp.Data.Request.Body)
assert.Equal(t, "{}", *successResp.Data.Request.Headers)
assert.Equal(t, "http://example.com", *successResp.Data.Request.Url)
}
if assert.NotNil(t, successResp.Data.Response) {
assert.Equal(t, "{}", *successResp.Data.Response.Body)
assert.Equal(t, "{}", *successResp.Data.Response.Headers)
assert.Equal(t, "OK", *successResp.Data.Response.Status)
assert.Equal(t, 200, *successResp.Data.Response.StatusCode)
}
assert.Equal(t, int64(1), *successResp.Data.Id)
assert.Equal(t, "", *successResp.Data.Error)
assert.Equal(t, api.WebhookExecResultSUCCESS, *successResp.Data.Result)
assert.Equal(t, api.TriggerARTIFACTCREATION, *successResp.Data.TriggerType)
case "permission_check_fails":
assert.IsType(t, api.ReTriggerWebhookExecution403JSONResponse{}, resp, "expected 403 response")
errorResp, _ := resp.(api.ReTriggerWebhookExecution403JSONResponse) //nolint:errcheck
assert.Equal(t, "403", errorResp.Code)
assert.Equal(t, "forbidden", errorResp.Message)
case "invalid_execution_identifier":
assert.IsType(t, api.ReTriggerWebhookExecution400JSONResponse{}, resp, "expected 400 response")
errorResp, _ := resp.(api.ReTriggerWebhookExecution400JSONResponse) //nolint:errcheck
assert.Equal(t, "400", errorResp.Code)
assert.Equal(t, "invalid webhook execution identifier: invalid, err: strconv.ParseInt: parsing \"invalid\": invalid syntax", errorResp.Message)
case "retrigger_execution_error":
assert.IsType(t, api.ReTriggerWebhookExecution500JSONResponse{}, resp, "expected 500 response")
errorResp, _ := resp.(api.ReTriggerWebhookExecution500JSONResponse) //nolint:errcheck
assert.Equal(t, "500", errorResp.Code)
assert.Equal(t, "failed to re-trigger execution: error", errorResp.Message)
}
// Verify all mock expectations
mockSpaceFinder.AssertExpectations(t)
mockRegistryRepository.AssertExpectations(t)
mockWebhooksRepository.AssertExpectations(t)
mockWebhooksExecutionRepository.AssertExpectations(t)
mockAuthorizer.AssertExpectations(t)
mockRegistryMetadataHelper.AssertExpectations(t)
mockWebhookService.AssertExpectations(t)
})
}
}

View File

@ -71,7 +71,7 @@ func (c *APIController) UpdateArtifactLabels(
a := string(r.Artifact)
artifactEntity, err := c.ImageStore.GetByRepoAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier, a)
artifactEntity, err := c.ImageStore.GetByRepoAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier, a)
if len(artifactEntity.Name) == 0 {
return artifact.UpdateArtifactLabels404JSONResponse{
@ -95,7 +95,7 @@ func (c *APIController) UpdateArtifactLabels(
}
// TODO: use the correct way to get download count if this endpoint is used
tag, err := c.TagStore.GetLatestTagMetadata(ctx, regInfo.parentID, regInfo.RegistryIdentifier, a)
tag, err := c.TagStore.GetLatestTagMetadata(ctx, regInfo.ParentID, regInfo.RegistryIdentifier, a)
if err != nil {
return artifact.UpdateArtifactLabels500JSONResponse{

View File

@ -68,7 +68,7 @@ func (c *APIController) ModifyRegistry(
}, err
}
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.parentID, regInfo.RegistryIdentifier)
repoEntity, err := c.RegistryRepository.GetByParentIDAndName(ctx, regInfo.ParentID, regInfo.RegistryIdentifier)
if err != nil {
return throwModifyRegistry500Error(err), err
}
@ -77,7 +77,7 @@ func (c *APIController) ModifyRegistry(
return c.updateVirtualRegistry(ctx, r, repoEntity, err, regInfo, session)
}
upstreamproxyEntity, err := c.UpstreamProxyStore.GetByRegistryIdentifier(
ctx, regInfo.parentID,
ctx, regInfo.ParentID,
regInfo.RegistryIdentifier,
)
if len(upstreamproxyEntity.RepoKey) == 0 {
@ -93,7 +93,7 @@ func (c *APIController) ModifyRegistry(
registry, upstreamproxy, err := c.UpdateUpstreamProxyEntity(
ctx,
artifact.RegistryRequest(*r.Body),
regInfo.parentID, regInfo.rootIdentifierID, upstreamproxyEntity,
regInfo.ParentID, regInfo.RootIdentifierID, upstreamproxyEntity,
)
registry.ID = repoEntity.ID
upstreamproxy.ID = upstreamproxyEntity.ID
@ -133,7 +133,7 @@ func (c *APIController) ModifyRegistry(
func (c *APIController) updateVirtualRegistry(
ctx context.Context, r artifact.ModifyRegistryRequestObject, repoEntity *types.Registry, err error,
regInfo *RegistryRequestBaseInfo, session *auth.Session,
regInfo *types.RegistryRequestBaseInfo, session *auth.Session,
) (artifact.ModifyRegistryResponseObject, error) {
if len(repoEntity.Name) == 0 {
return artifact.ModifyRegistry404JSONResponse{
@ -158,7 +158,7 @@ func (c *APIController) updateVirtualRegistry(
),
}, nil
}
err = c.setUpstreamProxyIDs(ctx, registry, artifact.RegistryRequest(*r.Body), regInfo.parentID)
err = c.setUpstreamProxyIDs(ctx, registry, artifact.RegistryRequest(*r.Body), regInfo.ParentID)
if err != nil {
return throwModifyRegistry500Error(err), nil
}
@ -393,7 +393,7 @@ func (c *APIController) UpdateUpstreamProxyEntity(
}
if res.SecretSpacePath != nil && len(*res.SecretSpacePath) > 0 {
upstreamProxyConfigEntity.SecretSpaceID, err = c.RegistryMetadataHelper.getSecretSpaceID(ctx, res.SecretSpacePath)
upstreamProxyConfigEntity.SecretSpaceID, err = c.RegistryMetadataHelper.GetSecretSpaceID(ctx, res.SecretSpacePath)
if err != nil {
return nil, nil, err
}
@ -414,7 +414,7 @@ func (c *APIController) UpdateUpstreamProxyEntity(
default:
if res.AccessKeySecretSpacePath != nil && len(*res.AccessKeySecretSpacePath) > 0 {
upstreamProxyConfigEntity.UserNameSecretSpaceID, err =
c.RegistryMetadataHelper.getSecretSpaceID(ctx, res.AccessKeySecretSpacePath)
c.RegistryMetadataHelper.GetSecretSpaceID(ctx, res.AccessKeySecretSpacePath)
if err != nil {
return nil, nil, err
}
@ -426,7 +426,7 @@ func (c *APIController) UpdateUpstreamProxyEntity(
if res.SecretKeySpacePath != nil && len(*res.SecretKeySpacePath) > 0 {
upstreamProxyConfigEntity.SecretSpaceID, err =
c.RegistryMetadataHelper.getSecretSpaceID(ctx, res.SecretKeySpacePath)
c.RegistryMetadataHelper.GetSecretSpaceID(ctx, res.SecretKeySpacePath)
if err != nil {
return nil, nil, err
}

View File

@ -12,151 +12,545 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
package metadata_test
import (
"testing"
"time"
"github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/stretchr/testify/assert"
)
func TestValidatePackageTypes_ValidTypes(t *testing.T) {
err := ValidatePackageTypes([]string{"DOCKER", "HELM"})
assert.NoError(t, err)
}
func TestValidatePackageTypes_InvalidTypes(t *testing.T) {
err := ValidatePackageTypes([]string{"INVALID"})
assert.Error(t, err)
assert.Equal(t, "invalid package type", err.Error())
}
func TestValidatePackageType_ValidType(t *testing.T) {
err := ValidatePackageType("DOCKER")
assert.NoError(t, err)
}
func TestValidatePackageType_InvalidType(t *testing.T) {
err := ValidatePackageType("INVALID")
assert.Error(t, err)
assert.Equal(t, "invalid package type", err.Error())
}
func TestValidateIdentifier_ValidIdentifier(t *testing.T) {
err := ValidateIdentifier("valid-identifier")
assert.NoError(t, err)
}
func TestValidateIdentifier_InvalidIdentifier(t *testing.T) {
err := ValidateIdentifier("Invalid Identifier")
assert.Error(t, err)
assert.Equal(t, RegistryIdentifierErrorMsg, err.Error())
}
func TestCleanURLPath_ValidURL(t *testing.T) {
input := "https://example.com/path/"
expected := "https://example.com/path"
CleanURLPath(&input)
assert.Equal(t, expected, input)
}
func TestCleanURLPath_InvalidURL(t *testing.T) {
input := "://invalid-url"
expected := "://invalid-url"
CleanURLPath(&input)
assert.Equal(t, expected, input)
}
func TestGetTimeInMs_ValidTime(t *testing.T) {
tm := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
expected := "1672531200000"
result := GetTimeInMs(tm)
assert.Equal(t, expected, result)
}
func TestGetErrorResponse_ValidError(t *testing.T) {
code := 404
message := "Not Found"
expected := &artifact.Error{
Code: "404",
Message: message,
func TestValidatePackageTypes(t *testing.T) {
tests := []struct {
name string
types []string
wantErr bool
errMsg string
}{
{
name: "valid_types",
types: []string{"DOCKER", "HELM"},
wantErr: false,
},
{
name: "invalid_type",
types: []string{"INVALID"},
wantErr: true,
errMsg: "invalid package type",
},
}
result := GetErrorResponse(code, message)
assert.Equal(t, expected, result)
}
func TestGetSortByOrder_ValidOrder(t *testing.T) {
assert.Equal(t, "ASC", GetSortByOrder(""))
assert.Equal(t, "DESC", GetSortByOrder("DESC"))
assert.Equal(t, "ASC", GetSortByOrder("INVALID"))
}
func TestGetSortByField_ValidField(t *testing.T) {
assert.Equal(t, "name", GetSortByField("identifier", RepositoryResource))
assert.Equal(t, "created_at", GetSortByField("invalid", RepositoryResource))
}
func TestGetPageLimit_ValidPageSize(t *testing.T) {
pageSize := artifact.PageSize(20)
assert.Equal(t, 20, GetPageLimit(&pageSize))
assert.Equal(t, 10, GetPageLimit(nil))
}
func TestGetOffset_ValidOffset(t *testing.T) {
pageSize := artifact.PageSize(20)
pageNumber := artifact.PageNumber(2)
assert.Equal(t, 40, GetOffset(&pageSize, &pageNumber))
assert.Equal(t, 0, GetOffset(nil, nil))
}
func TestGetPageNumber_ValidPageNumber(t *testing.T) {
pageNumber := artifact.PageNumber(2)
assert.Equal(t, int64(2), GetPageNumber(&pageNumber))
assert.Equal(t, int64(1), GetPageNumber(nil))
}
func TestGetSuccessResponse_ValidResponse(t *testing.T) {
expected := &artifact.Success{
Status: artifact.StatusSUCCESS,
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := metadata.ValidatePackageTypes(tt.types)
if tt.wantErr {
assert.Error(t, err)
assert.Equal(t, tt.errMsg, err.Error())
} else {
assert.NoError(t, err)
}
})
}
result := GetSuccessResponse()
assert.Equal(t, expected, result)
}
func TestGetPageCount_ValidCount(t *testing.T) {
assert.Equal(t, int64(5), GetPageCount(50, 10))
assert.Equal(t, int64(0), GetPageCount(0, 10))
func TestValidatePackageType(t *testing.T) {
tests := []struct {
name string
pkgType string
wantErr bool
errMsg string
}{
{
name: "valid_type",
pkgType: "DOCKER",
wantErr: false,
},
{
name: "invalid_type",
pkgType: "INVALID",
wantErr: true,
errMsg: "invalid package type",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := metadata.ValidatePackageType(tt.pkgType)
if tt.wantErr {
assert.Error(t, err)
assert.Equal(t, tt.errMsg, err.Error())
} else {
assert.NoError(t, err)
}
})
}
}
func TestGetRegistryRef_ValidRef(t *testing.T) {
assert.Equal(t, "root/registry", GetRegistryRef("root", "registry"))
func TestValidateIdentifier(t *testing.T) {
tests := []struct {
name string
identifier string
wantErr bool
errMsg string
}{
{
name: "valid_identifier",
identifier: "valid-identifier",
wantErr: false,
},
{
name: "invalid_identifier",
identifier: "Invalid Identifier",
wantErr: true,
errMsg: metadata.RegistryIdentifierErrorMsg,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := metadata.ValidateIdentifier(tt.identifier)
if tt.wantErr {
assert.Error(t, err)
assert.Equal(t, tt.errMsg, err.Error())
} else {
assert.NoError(t, err)
}
})
}
}
func TestGetRepoURLWithoutProtocol_ValidURL(t *testing.T) {
assert.Equal(t, "example.com/path", GetRepoURLWithoutProtocol("https://example.com/path"))
assert.Equal(t, "", GetRepoURLWithoutProtocol("://invalid-url"))
func TestCleanURLPath(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{
name: "valid_url",
input: "https://example.com/path/",
expected: "https://example.com/path",
},
{
name: "invalid_url",
input: "://invalid-url",
expected: "://invalid-url",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
input := tt.input
metadata.CleanURLPath(&input)
assert.Equal(t, tt.expected, input)
})
}
}
func TestGetTagURL_ValidURL(t *testing.T) {
assert.Equal(t, "https://example.com/artifact/version", GetTagURL("artifact", "version", "https://example.com"))
func TestGetTimeInMs(t *testing.T) {
tests := []struct {
name string
time time.Time
expected string
}{
{
name: "valid_time",
time: time.Unix(1234567890, 0),
expected: "1234567890000",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetTimeInMs(tt.time)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetPullCommand_ValidCommand(t *testing.T) {
assert.Equal(t, "docker pull example.com/image:tag",
GetPullCommand("image", "tag", "DOCKER", "https://example.com"))
assert.Equal(t, "helm pull oci://example.com/image --version tag",
GetPullCommand("image", "tag", "HELM", "https://example.com"))
assert.Equal(t, "", GetPullCommand("image", "tag", "INVALID", "https://example.com"))
func TestGetPullCommand(t *testing.T) {
tests := []struct {
name string
image string
tag string
pkgType string
baseURL string
expected string
}{
{
name: "docker_command",
image: "image",
tag: "tag",
pkgType: "DOCKER",
baseURL: "https://example.com",
expected: "docker pull example.com/image:tag",
},
{
name: "helm_command",
image: "image",
tag: "tag",
pkgType: "HELM",
baseURL: "https://example.com",
expected: "helm pull oci://example.com/image --version tag",
},
{
name: "invalid_type",
image: "image",
tag: "tag",
pkgType: "INVALID",
baseURL: "https://example.com",
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetPullCommand(tt.image, tt.tag, tt.pkgType, tt.baseURL)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetDockerPullCommand_ValidCommand(t *testing.T) {
assert.Equal(t, "docker pull example.com/image:tag", GetDockerPullCommand("image", "tag", "https://example.com"))
func TestGetDockerPullCommand(t *testing.T) {
tests := []struct {
name string
image string
tag string
baseURL string
expected string
}{
{
name: "valid_command",
image: "image",
tag: "tag",
baseURL: "https://example.com",
expected: "docker pull example.com/image:tag",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetDockerPullCommand(tt.image, tt.tag, tt.baseURL)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetHelmPullCommand_ValidCommand(t *testing.T) {
assert.Equal(t, "helm pull oci://example.com/image --version tag",
GetHelmPullCommand("image", "tag", "https://example.com"))
func TestGetHelmPullCommand(t *testing.T) {
tests := []struct {
name string
image string
tag string
baseURL string
expected string
}{
{
name: "valid_command",
image: "image",
tag: "tag",
baseURL: "https://example.com",
expected: "helm pull oci://example.com/image --version tag",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetHelmPullCommand(tt.image, tt.tag, tt.baseURL)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetErrorResponse(t *testing.T) {
tests := []struct {
name string
code int
message string
expected *artifact.Error
}{
{
name: "valid_error",
code: 404,
message: "Not Found",
expected: &artifact.Error{
Code: "404",
Message: "Not Found",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetErrorResponse(tt.code, tt.message)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetSortByOrder(t *testing.T) {
tests := []struct {
name string
order string
expected string
}{
{
name: "empty_order",
order: "",
expected: "ASC",
},
{
name: "desc_order",
order: "DESC",
expected: "DESC",
},
{
name: "invalid_order",
order: "INVALID",
expected: "ASC",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetSortByOrder(tt.order)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetSortByField(t *testing.T) {
tests := []struct {
name string
field string
resource string
expected string
}{
{
name: "identifier_field",
field: "identifier",
resource: "repository",
expected: "name",
},
{
name: "invalid_field",
field: "invalid",
resource: "repository",
expected: "created_at",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetSortByField(tt.field, tt.resource)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetPageLimit(t *testing.T) {
tests := []struct {
name string
pageSize *artifact.PageSize
expected int
}{
{
name: "valid_page_size",
pageSize: func() *artifact.PageSize { ps := artifact.PageSize(20); return &ps }(),
expected: 20,
},
{
name: "nil_page_size",
pageSize: nil,
expected: 10,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetPageLimit(tt.pageSize)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetOffset(t *testing.T) {
tests := []struct {
name string
pageSize *artifact.PageSize
pageNumber *artifact.PageNumber
expected int
}{
{
name: "valid_offset",
pageSize: func() *artifact.PageSize { ps := artifact.PageSize(20); return &ps }(),
pageNumber: func() *artifact.PageNumber { pn := artifact.PageNumber(2); return &pn }(),
expected: 40,
},
{
name: "nil_values",
pageSize: nil,
pageNumber: nil,
expected: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetOffset(tt.pageSize, tt.pageNumber)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetPageNumber(t *testing.T) {
tests := []struct {
name string
pageNumber *artifact.PageNumber
expected int64
}{
{
name: "valid_page_number",
pageNumber: func() *artifact.PageNumber { pn := artifact.PageNumber(2); return &pn }(),
expected: 2,
},
{
name: "nil_page_number",
pageNumber: nil,
expected: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetPageNumber(tt.pageNumber)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetSuccessResponse(t *testing.T) {
tests := []struct {
name string
expected *artifact.Success
}{
{
name: "valid_response",
expected: &artifact.Success{
Status: artifact.StatusSUCCESS,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetSuccessResponse()
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetPageCount(t *testing.T) {
tests := []struct {
name string
count int64
limit int
expected int64
}{
{
name: "valid_count",
count: 50,
limit: 10,
expected: 5,
},
{
name: "zero_count",
count: 0,
limit: 10,
expected: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetPageCount(tt.count, tt.limit)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetRegistryRef(t *testing.T) {
tests := []struct {
name string
root string
registry string
expected string
}{
{
name: "valid_ref",
root: "root",
registry: "registry",
expected: "root/registry",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetRegistryRef(tt.root, tt.registry)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetRepoURLWithoutProtocol(t *testing.T) {
tests := []struct {
name string
url string
expected string
}{
{
name: "valid_url",
url: "https://example.com/path",
expected: "example.com/path",
},
{
name: "invalid_url",
url: "://invalid-url",
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetRepoURLWithoutProtocol(tt.url)
assert.Equal(t, tt.expected, result)
})
}
}
func TestGetTagURL(t *testing.T) {
tests := []struct {
name string
artifact string
version string
baseURL string
expected string
}{
{
name: "valid_url",
artifact: "artifact",
version: "version",
baseURL: "https://example.com",
expected: "https://example.com/artifact/version",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetTagURL(tt.artifact, tt.version, tt.baseURL)
assert.Equal(t, tt.expected, result)
})
}
}

View File

@ -0,0 +1,370 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
mock "github.com/stretchr/testify/mock"
)
// ArtifactRepository is an autogenerated mock type for the ArtifactRepository type
type ArtifactRepository struct {
mock.Mock
}
// Count provides a mock function with given fields: ctx
func (_m *ArtifactRepository) Count(ctx context.Context) (int64, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for Count")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (int64, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) int64); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountAllArtifactsByParentID provides a mock function with given fields: ctx, parentID, registryIDs, search, latestVersion, packageTypes
func (_m *ArtifactRepository) CountAllArtifactsByParentID(ctx context.Context, parentID int64, registryIDs *[]string, search string, latestVersion bool, packageTypes []string) (int64, error) {
ret := _m.Called(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
if len(ret) == 0 {
panic("no return value specified for CountAllArtifactsByParentID")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, bool, []string) (int64, error)); ok {
return rf(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, bool, []string) int64); ok {
r0 = rf(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, *[]string, string, bool, []string) error); ok {
r1 = rf(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountAllArtifactsByRepo provides a mock function with given fields: ctx, parentID, repoKey, search, labels
func (_m *ArtifactRepository) CountAllArtifactsByRepo(ctx context.Context, parentID int64, repoKey string, search string, labels []string) (int64, error) {
ret := _m.Called(ctx, parentID, repoKey, search, labels)
if len(ret) == 0 {
panic("no return value specified for CountAllArtifactsByRepo")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, []string) (int64, error)); ok {
return rf(ctx, parentID, repoKey, search, labels)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, []string) int64); ok {
r0 = rf(ctx, parentID, repoKey, search, labels)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, []string) error); ok {
r1 = rf(ctx, parentID, repoKey, search, labels)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountAllVersionsByRepoAndImage provides a mock function with given fields: ctx, parentID, repoKey, image, search
func (_m *ArtifactRepository) CountAllVersionsByRepoAndImage(ctx context.Context, parentID int64, repoKey string, image string, search string) (int64, error) {
ret := _m.Called(ctx, parentID, repoKey, image, search)
if len(ret) == 0 {
panic("no return value specified for CountAllVersionsByRepoAndImage")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) (int64, error)); ok {
return rf(ctx, parentID, repoKey, image, search)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) int64); ok {
r0 = rf(ctx, parentID, repoKey, image, search)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string) error); ok {
r1 = rf(ctx, parentID, repoKey, image, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CreateOrUpdate provides a mock function with given fields: ctx, artifact
func (_m *ArtifactRepository) CreateOrUpdate(ctx context.Context, artifact *types.Artifact) error {
ret := _m.Called(ctx, artifact)
if len(ret) == 0 {
panic("no return value specified for CreateOrUpdate")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Artifact) error); ok {
r0 = rf(ctx, artifact)
} else {
r0 = ret.Error(0)
}
return r0
}
// GetAllArtifactsByParentID provides a mock function with given fields: ctx, id, i, field, order, limit, offset, term, version, packageTypes
func (_m *ArtifactRepository) GetAllArtifactsByParentID(ctx context.Context, id int64, i *[]string, field string, order string, limit int, offset int, term string, version bool, packageTypes []string) (*[]types.ArtifactMetadata, error) {
ret := _m.Called(ctx, id, i, field, order, limit, offset, term, version, packageTypes)
if len(ret) == 0 {
panic("no return value specified for GetAllArtifactsByParentID")
}
var r0 *[]types.ArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, string, int, int, string, bool, []string) (*[]types.ArtifactMetadata, error)); ok {
return rf(ctx, id, i, field, order, limit, offset, term, version, packageTypes)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, string, int, int, string, bool, []string) *[]types.ArtifactMetadata); ok {
r0 = rf(ctx, id, i, field, order, limit, offset, term, version, packageTypes)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.ArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, *[]string, string, string, int, int, string, bool, []string) error); ok {
r1 = rf(ctx, id, i, field, order, limit, offset, term, version, packageTypes)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAllArtifactsByRepo provides a mock function with given fields: ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels
func (_m *ArtifactRepository) GetAllArtifactsByRepo(ctx context.Context, parentID int64, repoKey string, sortByField string, sortByOrder string, limit int, offset int, search string, labels []string) (*[]types.ArtifactMetadata, error) {
ret := _m.Called(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
if len(ret) == 0 {
panic("no return value specified for GetAllArtifactsByRepo")
}
var r0 *[]types.ArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, int, int, string, []string) (*[]types.ArtifactMetadata, error)); ok {
return rf(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, int, int, string, []string) *[]types.ArtifactMetadata); ok {
r0 = rf(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.ArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string, int, int, string, []string) error); ok {
r1 = rf(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAllVersionsByRepoAndImage provides a mock function with given fields: ctx, id, identifier, image, field, order, limit, offset, term
func (_m *ArtifactRepository) GetAllVersionsByRepoAndImage(ctx context.Context, id int64, identifier string, image string, field string, order string, limit int, offset int, term string) (*[]types.NonOCIArtifactMetadata, error) {
ret := _m.Called(ctx, id, identifier, image, field, order, limit, offset, term)
if len(ret) == 0 {
panic("no return value specified for GetAllVersionsByRepoAndImage")
}
var r0 *[]types.NonOCIArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, string, int, int, string) (*[]types.NonOCIArtifactMetadata, error)); ok {
return rf(ctx, id, identifier, image, field, order, limit, offset, term)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, string, int, int, string) *[]types.NonOCIArtifactMetadata); ok {
r0 = rf(ctx, id, identifier, image, field, order, limit, offset, term)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.NonOCIArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string, string, int, int, string) error); ok {
r1 = rf(ctx, id, identifier, image, field, order, limit, offset, term)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetArtifactMetadata provides a mock function with given fields: ctx, id, identifier, image, version
func (_m *ArtifactRepository) GetArtifactMetadata(ctx context.Context, id int64, identifier string, image string, version string) (*types.ArtifactMetadata, error) {
ret := _m.Called(ctx, id, identifier, image, version)
if len(ret) == 0 {
panic("no return value specified for GetArtifactMetadata")
}
var r0 *types.ArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) (*types.ArtifactMetadata, error)); ok {
return rf(ctx, id, identifier, image, version)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) *types.ArtifactMetadata); ok {
r0 = rf(ctx, id, identifier, image, version)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string) error); ok {
r1 = rf(ctx, id, identifier, image, version)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByName provides a mock function with given fields: ctx, imageID, version
func (_m *ArtifactRepository) GetByName(ctx context.Context, imageID int64, version string) (*types.Artifact, error) {
ret := _m.Called(ctx, imageID, version)
if len(ret) == 0 {
panic("no return value specified for GetByName")
}
var r0 *types.Artifact
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*types.Artifact, error)); ok {
return rf(ctx, imageID, version)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.Artifact); ok {
r0 = rf(ctx, imageID, version)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Artifact)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, imageID, version)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByRegistryIDAndImage provides a mock function with given fields: ctx, registryID, image
func (_m *ArtifactRepository) GetByRegistryIDAndImage(ctx context.Context, registryID int64, image string) (*[]types.Artifact, error) {
ret := _m.Called(ctx, registryID, image)
if len(ret) == 0 {
panic("no return value specified for GetByRegistryIDAndImage")
}
var r0 *[]types.Artifact
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*[]types.Artifact, error)); ok {
return rf(ctx, registryID, image)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *[]types.Artifact); ok {
r0 = rf(ctx, registryID, image)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.Artifact)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, registryID, image)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetLatestArtifactMetadata provides a mock function with given fields: ctx, id, identifier, image
func (_m *ArtifactRepository) GetLatestArtifactMetadata(ctx context.Context, id int64, identifier string, image string) (*types.ArtifactMetadata, error) {
ret := _m.Called(ctx, id, identifier, image)
if len(ret) == 0 {
panic("no return value specified for GetLatestArtifactMetadata")
}
var r0 *types.ArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (*types.ArtifactMetadata, error)); ok {
return rf(ctx, id, identifier, image)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) *types.ArtifactMetadata); ok {
r0 = rf(ctx, id, identifier, image)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, id, identifier, image)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewArtifactRepository creates a new instance of ArtifactRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewArtifactRepository(t interface {
mock.TestingT
Cleanup(func())
}) *ArtifactRepository {
mock := &ArtifactRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,42 @@
// Code generated by testify. DO NOT EDIT.
package mocks
import (
"context"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/types"
"github.com/stretchr/testify/mock"
)
// AuditService is a mock of audit.Service interface.
type AuditService struct {
mock.Mock
}
// Log provides a mock function
func (m *AuditService) Log(
ctx context.Context,
user types.Principal,
resource audit.Resource,
action audit.Action,
spacePath string,
options ...audit.Option,
) error {
args := []interface{}{ctx, user, resource, action, spacePath}
for _, opt := range options {
args = append(args, opt)
}
ret := m.Called(args...)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, types.Principal, audit.Resource, audit.Action, string, ...audit.Option) error); ok {
r0 = rf(ctx, user, resource, action, spacePath, options...)
} else {
r0 = ret.Error(0)
}
return r0
}

View File

@ -0,0 +1,65 @@
// Code generated by testify. DO NOT EDIT.
package mocks
import (
"context"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/mock"
)
// Authorizer is an autogenerated mock type for the Authorizer type
type Authorizer struct {
mock.Mock
}
// Check provides a mock function with given fields: ctx, session, scope, resource, permission
func (m *Authorizer) Check(ctx context.Context, session *auth.Session, scope *types.Scope, resource *types.Resource, permission enum.Permission) (bool, error) {
ret := m.Called(ctx, session, scope, resource, permission)
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, *auth.Session, *types.Scope, *types.Resource, enum.Permission) bool); ok {
r0 = rf(ctx, session, scope, resource, permission)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *auth.Session, *types.Scope, *types.Resource, enum.Permission) error); ok {
r1 = rf(ctx, session, scope, resource, permission)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CheckAll provides a mock function with given fields: ctx, session, permissionChecks
func (m *Authorizer) CheckAll(ctx context.Context, session *auth.Session, permissionChecks ...types.PermissionCheck) (bool, error) {
var args []interface{}
args = append(args, ctx, session)
for _, check := range permissionChecks {
args = append(args, check)
}
ret := m.Called(args...)
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, *auth.Session, ...types.PermissionCheck) bool); ok {
r0 = rf(ctx, session, permissionChecks...)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *auth.Session, ...types.PermissionCheck) error); ok {
r1 = rf(ctx, session, permissionChecks...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -0,0 +1,232 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
digest "github.com/opencontainers/go-digest"
mock "github.com/stretchr/testify/mock"
)
// BlobRepository is an autogenerated mock type for the BlobRepository type
type BlobRepository struct {
mock.Mock
}
// CreateOrFind provides a mock function with given fields: ctx, b
func (_m *BlobRepository) CreateOrFind(ctx context.Context, b *types.Blob) (*types.Blob, bool, error) {
ret := _m.Called(ctx, b)
if len(ret) == 0 {
panic("no return value specified for CreateOrFind")
}
var r0 *types.Blob
var r1 bool
var r2 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Blob) (*types.Blob, bool, error)); ok {
return rf(ctx, b)
}
if rf, ok := ret.Get(0).(func(context.Context, *types.Blob) *types.Blob); ok {
r0 = rf(ctx, b)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Blob)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *types.Blob) bool); ok {
r1 = rf(ctx, b)
} else {
r1 = ret.Get(1).(bool)
}
if rf, ok := ret.Get(2).(func(context.Context, *types.Blob) error); ok {
r2 = rf(ctx, b)
} else {
r2 = ret.Error(2)
}
return r0, r1, r2
}
// DeleteByID provides a mock function with given fields: ctx, id
func (_m *BlobRepository) DeleteByID(ctx context.Context, id int64) error {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for DeleteByID")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, id)
} else {
r0 = ret.Error(0)
}
return r0
}
// ExistsBlob provides a mock function with given fields: ctx, repoID, d, image
func (_m *BlobRepository) ExistsBlob(ctx context.Context, repoID int64, d digest.Digest, image string) (bool, error) {
ret := _m.Called(ctx, repoID, d, image)
if len(ret) == 0 {
panic("no return value specified for ExistsBlob")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, digest.Digest, string) (bool, error)); ok {
return rf(ctx, repoID, d, image)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, digest.Digest, string) bool); ok {
r0 = rf(ctx, repoID, d, image)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, digest.Digest, string) error); ok {
r1 = rf(ctx, repoID, d, image)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindByDigestAndRepoID provides a mock function with given fields: ctx, d, repoID, imageName
func (_m *BlobRepository) FindByDigestAndRepoID(ctx context.Context, d digest.Digest, repoID int64, imageName string) (*types.Blob, error) {
ret := _m.Called(ctx, d, repoID, imageName)
if len(ret) == 0 {
panic("no return value specified for FindByDigestAndRepoID")
}
var r0 *types.Blob
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, digest.Digest, int64, string) (*types.Blob, error)); ok {
return rf(ctx, d, repoID, imageName)
}
if rf, ok := ret.Get(0).(func(context.Context, digest.Digest, int64, string) *types.Blob); ok {
r0 = rf(ctx, d, repoID, imageName)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Blob)
}
}
if rf, ok := ret.Get(1).(func(context.Context, digest.Digest, int64, string) error); ok {
r1 = rf(ctx, d, repoID, imageName)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindByDigestAndRootParentID provides a mock function with given fields: ctx, d, rootParentID
func (_m *BlobRepository) FindByDigestAndRootParentID(ctx context.Context, d digest.Digest, rootParentID int64) (*types.Blob, error) {
ret := _m.Called(ctx, d, rootParentID)
if len(ret) == 0 {
panic("no return value specified for FindByDigestAndRootParentID")
}
var r0 *types.Blob
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, digest.Digest, int64) (*types.Blob, error)); ok {
return rf(ctx, d, rootParentID)
}
if rf, ok := ret.Get(0).(func(context.Context, digest.Digest, int64) *types.Blob); ok {
r0 = rf(ctx, d, rootParentID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Blob)
}
}
if rf, ok := ret.Get(1).(func(context.Context, digest.Digest, int64) error); ok {
r1 = rf(ctx, d, rootParentID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindByID provides a mock function with given fields: ctx, id
func (_m *BlobRepository) FindByID(ctx context.Context, id int64) (*types.Blob, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for FindByID")
}
var r0 *types.Blob
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (*types.Blob, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.Blob); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Blob)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// TotalSizeByRootParentID provides a mock function with given fields: ctx, id
func (_m *BlobRepository) TotalSizeByRootParentID(ctx context.Context, id int64) (int64, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for TotalSizeByRootParentID")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (int64, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) int64); ok {
r0 = rf(ctx, id)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewBlobRepository creates a new instance of BlobRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewBlobRepository(t interface {
mock.TestingT
Cleanup(func())
}) *BlobRepository {
mock := &BlobRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,308 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
mock "github.com/stretchr/testify/mock"
)
// CleanupPolicyRepository is an autogenerated mock type for the CleanupPolicyRepository type
type CleanupPolicyRepository struct {
mock.Mock
}
type CleanupPolicyRepository_Expecter struct {
mock *mock.Mock
}
func (_m *CleanupPolicyRepository) EXPECT() *CleanupPolicyRepository_Expecter {
return &CleanupPolicyRepository_Expecter{mock: &_m.Mock}
}
// Create provides a mock function with given fields: ctx, cleanupPolicy
func (_m *CleanupPolicyRepository) Create(ctx context.Context, cleanupPolicy *types.CleanupPolicy) (int64, error) {
ret := _m.Called(ctx, cleanupPolicy)
if len(ret) == 0 {
panic("no return value specified for Create")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *types.CleanupPolicy) (int64, error)); ok {
return rf(ctx, cleanupPolicy)
}
if rf, ok := ret.Get(0).(func(context.Context, *types.CleanupPolicy) int64); ok {
r0 = rf(ctx, cleanupPolicy)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, *types.CleanupPolicy) error); ok {
r1 = rf(ctx, cleanupPolicy)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CleanupPolicyRepository_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create'
type CleanupPolicyRepository_Create_Call struct {
*mock.Call
}
// Create is a helper method to define mock.On call
// - ctx context.Context
// - cleanupPolicy *types.CleanupPolicy
func (_e *CleanupPolicyRepository_Expecter) Create(ctx interface{}, cleanupPolicy interface{}) *CleanupPolicyRepository_Create_Call {
return &CleanupPolicyRepository_Create_Call{Call: _e.mock.On("Create", ctx, cleanupPolicy)}
}
func (_c *CleanupPolicyRepository_Create_Call) Run(run func(ctx context.Context, cleanupPolicy *types.CleanupPolicy)) *CleanupPolicyRepository_Create_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*types.CleanupPolicy))
})
return _c
}
func (_c *CleanupPolicyRepository_Create_Call) Return(id int64, err error) *CleanupPolicyRepository_Create_Call {
_c.Call.Return(id, err)
return _c
}
func (_c *CleanupPolicyRepository_Create_Call) RunAndReturn(run func(context.Context, *types.CleanupPolicy) (int64, error)) *CleanupPolicyRepository_Create_Call {
_c.Call.Return(run)
return _c
}
// Delete provides a mock function with given fields: ctx, id
func (_m *CleanupPolicyRepository) Delete(ctx context.Context, id int64) error {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for Delete")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, id)
} else {
r0 = ret.Error(0)
}
return r0
}
// CleanupPolicyRepository_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete'
type CleanupPolicyRepository_Delete_Call struct {
*mock.Call
}
// Delete is a helper method to define mock.On call
// - ctx context.Context
// - id int64
func (_e *CleanupPolicyRepository_Expecter) Delete(ctx interface{}, id interface{}) *CleanupPolicyRepository_Delete_Call {
return &CleanupPolicyRepository_Delete_Call{Call: _e.mock.On("Delete", ctx, id)}
}
func (_c *CleanupPolicyRepository_Delete_Call) Run(run func(ctx context.Context, id int64)) *CleanupPolicyRepository_Delete_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(int64))
})
return _c
}
func (_c *CleanupPolicyRepository_Delete_Call) Return(err error) *CleanupPolicyRepository_Delete_Call {
_c.Call.Return(err)
return _c
}
func (_c *CleanupPolicyRepository_Delete_Call) RunAndReturn(run func(context.Context, int64) error) *CleanupPolicyRepository_Delete_Call {
_c.Call.Return(run)
return _c
}
// GetByRegistryID provides a mock function with given fields: ctx, id
func (_m *CleanupPolicyRepository) GetByRegistryID(ctx context.Context, id int64) (*[]types.CleanupPolicy, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for GetByRegistryID")
}
var r0 *[]types.CleanupPolicy
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (*[]types.CleanupPolicy, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) *[]types.CleanupPolicy); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.CleanupPolicy)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CleanupPolicyRepository_GetByRegistryID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetByRegistryID'
type CleanupPolicyRepository_GetByRegistryID_Call struct {
*mock.Call
}
// GetByRegistryID is a helper method to define mock.On call
// - ctx context.Context
// - id int64
func (_e *CleanupPolicyRepository_Expecter) GetByRegistryID(ctx interface{}, id interface{}) *CleanupPolicyRepository_GetByRegistryID_Call {
return &CleanupPolicyRepository_GetByRegistryID_Call{Call: _e.mock.On("GetByRegistryID", ctx, id)}
}
func (_c *CleanupPolicyRepository_GetByRegistryID_Call) Run(run func(ctx context.Context, id int64)) *CleanupPolicyRepository_GetByRegistryID_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(int64))
})
return _c
}
func (_c *CleanupPolicyRepository_GetByRegistryID_Call) Return(cleanupPolicies *[]types.CleanupPolicy, err error) *CleanupPolicyRepository_GetByRegistryID_Call {
_c.Call.Return(cleanupPolicies, err)
return _c
}
func (_c *CleanupPolicyRepository_GetByRegistryID_Call) RunAndReturn(run func(context.Context, int64) (*[]types.CleanupPolicy, error)) *CleanupPolicyRepository_GetByRegistryID_Call {
_c.Call.Return(run)
return _c
}
// GetIDsByRegistryID provides a mock function with given fields: ctx, id
func (_m *CleanupPolicyRepository) GetIDsByRegistryID(ctx context.Context, id int64) ([]int64, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for GetIDsByRegistryID")
}
var r0 []int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) ([]int64, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) []int64); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]int64)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CleanupPolicyRepository_GetIDsByRegistryID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetIDsByRegistryID'
type CleanupPolicyRepository_GetIDsByRegistryID_Call struct {
*mock.Call
}
// GetIDsByRegistryID is a helper method to define mock.On call
// - ctx context.Context
// - id int64
func (_e *CleanupPolicyRepository_Expecter) GetIDsByRegistryID(ctx interface{}, id interface{}) *CleanupPolicyRepository_GetIDsByRegistryID_Call {
return &CleanupPolicyRepository_GetIDsByRegistryID_Call{Call: _e.mock.On("GetIDsByRegistryID", ctx, id)}
}
func (_c *CleanupPolicyRepository_GetIDsByRegistryID_Call) Run(run func(ctx context.Context, id int64)) *CleanupPolicyRepository_GetIDsByRegistryID_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(int64))
})
return _c
}
func (_c *CleanupPolicyRepository_GetIDsByRegistryID_Call) Return(ids []int64, err error) *CleanupPolicyRepository_GetIDsByRegistryID_Call {
_c.Call.Return(ids, err)
return _c
}
func (_c *CleanupPolicyRepository_GetIDsByRegistryID_Call) RunAndReturn(run func(context.Context, int64) ([]int64, error)) *CleanupPolicyRepository_GetIDsByRegistryID_Call {
_c.Call.Return(run)
return _c
}
// ModifyCleanupPolicies provides a mock function with given fields: ctx, cleanupPolicies, ids
func (_m *CleanupPolicyRepository) ModifyCleanupPolicies(ctx context.Context, cleanupPolicies *[]types.CleanupPolicy, ids []int64) error {
ret := _m.Called(ctx, cleanupPolicies, ids)
if len(ret) == 0 {
panic("no return value specified for ModifyCleanupPolicies")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *[]types.CleanupPolicy, []int64) error); ok {
r0 = rf(ctx, cleanupPolicies, ids)
} else {
r0 = ret.Error(0)
}
return r0
}
// CleanupPolicyRepository_ModifyCleanupPolicies_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ModifyCleanupPolicies'
type CleanupPolicyRepository_ModifyCleanupPolicies_Call struct {
*mock.Call
}
// ModifyCleanupPolicies is a helper method to define mock.On call
// - ctx context.Context
// - cleanupPolicies *[]types.CleanupPolicy
// - ids []int64
func (_e *CleanupPolicyRepository_Expecter) ModifyCleanupPolicies(ctx interface{}, cleanupPolicies interface{}, ids interface{}) *CleanupPolicyRepository_ModifyCleanupPolicies_Call {
return &CleanupPolicyRepository_ModifyCleanupPolicies_Call{Call: _e.mock.On("ModifyCleanupPolicies", ctx, cleanupPolicies, ids)}
}
func (_c *CleanupPolicyRepository_ModifyCleanupPolicies_Call) Run(run func(ctx context.Context, cleanupPolicies *[]types.CleanupPolicy, ids []int64)) *CleanupPolicyRepository_ModifyCleanupPolicies_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*[]types.CleanupPolicy), args[2].([]int64))
})
return _c
}
func (_c *CleanupPolicyRepository_ModifyCleanupPolicies_Call) Return(_a0 error) *CleanupPolicyRepository_ModifyCleanupPolicies_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *CleanupPolicyRepository_ModifyCleanupPolicies_Call) RunAndReturn(run func(context.Context, *[]types.CleanupPolicy, []int64) error) *CleanupPolicyRepository_ModifyCleanupPolicies_Call {
_c.Call.Return(run)
return _c
}
// NewCleanupPolicyRepository creates a new instance of CleanupPolicyRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewCleanupPolicyRepository(t interface {
mock.TestingT
Cleanup(func())
}) *CleanupPolicyRepository {
mock := &CleanupPolicyRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,100 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
multipart "mime/multipart"
pkgpython "github.com/harness/gitness/registry/app/api/controller/pkg/python"
python "github.com/harness/gitness/registry/app/pkg/types/python"
mock "github.com/stretchr/testify/mock"
)
// Controller is an autogenerated mock type for the Controller type
type Controller struct {
mock.Mock
}
// DownloadPackageFile provides a mock function with given fields: ctx, info
func (_m *Controller) DownloadPackageFile(ctx context.Context, info python.ArtifactInfo) *pkgpython.GetArtifactResponse {
ret := _m.Called(ctx, info)
if len(ret) == 0 {
panic("no return value specified for DownloadPackageFile")
}
var r0 *pkgpython.GetArtifactResponse
if rf, ok := ret.Get(0).(func(context.Context, python.ArtifactInfo) *pkgpython.GetArtifactResponse); ok {
r0 = rf(ctx, info)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*pkgpython.GetArtifactResponse)
}
}
return r0
}
// GetPackageMetadata provides a mock function with given fields: ctx, info
func (_m *Controller) GetPackageMetadata(ctx context.Context, info python.ArtifactInfo) (python.PackageMetadata, error) {
ret := _m.Called(ctx, info)
if len(ret) == 0 {
panic("no return value specified for GetPackageMetadata")
}
var r0 python.PackageMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, python.ArtifactInfo) (python.PackageMetadata, error)); ok {
return rf(ctx, info)
}
if rf, ok := ret.Get(0).(func(context.Context, python.ArtifactInfo) python.PackageMetadata); ok {
r0 = rf(ctx, info)
} else {
r0 = ret.Get(0).(python.PackageMetadata)
}
if rf, ok := ret.Get(1).(func(context.Context, python.ArtifactInfo) error); ok {
r1 = rf(ctx, info)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// UploadPackageFile provides a mock function with given fields: ctx, info, file, fileHeader
func (_m *Controller) UploadPackageFile(ctx context.Context, info python.ArtifactInfo, file multipart.File, fileHeader *multipart.FileHeader) *pkgpython.PutArtifactResponse {
ret := _m.Called(ctx, info, file, fileHeader)
if len(ret) == 0 {
panic("no return value specified for UploadPackageFile")
}
var r0 *pkgpython.PutArtifactResponse
if rf, ok := ret.Get(0).(func(context.Context, python.ArtifactInfo, multipart.File, *multipart.FileHeader) *pkgpython.PutArtifactResponse); ok {
r0 = rf(ctx, info, file, fileHeader)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*pkgpython.PutArtifactResponse)
}
}
return r0
}
// NewController creates a new instance of Controller. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewController(t interface {
mock.TestingT
Cleanup(func())
}) *Controller {
mock := &Controller{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,67 @@
// Code generated by mockery. DO NOT EDIT.
package mocks
import (
"context"
"io"
"mime/multipart"
"github.com/harness/gitness/registry/app/storage"
"github.com/harness/gitness/registry/types"
"github.com/stretchr/testify/mock"
)
// FileManager is a mock type for filemanager.FileManager
type FileManager struct {
mock.Mock
}
// UploadFile provides a mock function
func (m *FileManager) UploadFile(ctx context.Context, filePath string, regName string, regID int64, rootParentID int64, rootIdentifier string, file multipart.File, fileReader io.Reader, filename string) (types.FileInfo, error) {
args := m.Called(ctx, filePath, regName, regID, rootParentID, rootIdentifier, file, fileReader, filename)
return args.Get(0).(types.FileInfo), args.Error(1)
}
// DownloadFile provides a mock function
func (m *FileManager) DownloadFile(ctx context.Context, filePath string, regInfo types.Registry, rootIdentifier string) (*storage.FileReader, int64, string, error) {
args := m.Called(ctx, filePath, regInfo, rootIdentifier)
return args.Get(0).(*storage.FileReader), args.Get(1).(int64), args.Get(2).(string), args.Error(3)
}
// DeleteFile provides a mock function
func (m *FileManager) DeleteFile(ctx context.Context, filePath string, regID int) error {
args := m.Called(ctx, filePath, regID)
return args.Error(0)
}
// HeadFile provides a mock function
func (m *FileManager) HeadFile(ctx context.Context, filePath string, regID int64) (string, error) {
args := m.Called(ctx, filePath, regID)
return args.String(0), args.Error(1)
}
// GetFileMetadata provides a mock function
func (m *FileManager) GetFileMetadata(ctx context.Context, filePath string, regID int64) (types.FileInfo, error) {
args := m.Called(ctx, filePath, regID)
return args.Get(0).(types.FileInfo), args.Error(1)
}
// DeleteFileByRegistryID provides a mock function
func (m *FileManager) DeleteFileByRegistryID(ctx context.Context, regID int64, regName string) error {
args := m.Called(ctx, regID, regName)
return args.Error(0)
}
// GetFilesMetadata provides a mock function
func (m *FileManager) GetFilesMetadata(ctx context.Context, filePath string, regID int64, sortByField string, sortByOrder string, limit int, offset int, search string) (*[]types.FileNodeMetadata, error) {
args := m.Called(ctx, filePath, regID, sortByField, sortByOrder, limit, offset, search)
return args.Get(0).(*[]types.FileNodeMetadata), args.Error(1)
}
// CountFilesByPath provides a mock function
func (m *FileManager) CountFilesByPath(ctx context.Context, filePath string, regID int64) (int64, error) {
args := m.Called(ctx, filePath, regID)
return args.Get(0).(int64), args.Error(1)
}

View File

@ -0,0 +1,164 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
mock "github.com/stretchr/testify/mock"
)
// GenericBlobRepository is an autogenerated mock type for the GenericBlobRepository type
type GenericBlobRepository struct {
mock.Mock
}
// Create provides a mock function with given fields: ctx, gb
func (_m *GenericBlobRepository) Create(ctx context.Context, gb *types.GenericBlob) (bool, error) {
ret := _m.Called(ctx, gb)
if len(ret) == 0 {
panic("no return value specified for Create")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *types.GenericBlob) (bool, error)); ok {
return rf(ctx, gb)
}
if rf, ok := ret.Get(0).(func(context.Context, *types.GenericBlob) bool); ok {
r0 = rf(ctx, gb)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, *types.GenericBlob) error); ok {
r1 = rf(ctx, gb)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DeleteByID provides a mock function with given fields: ctx, id
func (_m *GenericBlobRepository) DeleteByID(ctx context.Context, id string) error {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for DeleteByID")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
r0 = rf(ctx, id)
} else {
r0 = ret.Error(0)
}
return r0
}
// FindByID provides a mock function with given fields: ctx, id
func (_m *GenericBlobRepository) FindByID(ctx context.Context, id string) (*types.GenericBlob, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for FindByID")
}
var r0 *types.GenericBlob
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (*types.GenericBlob, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, string) *types.GenericBlob); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.GenericBlob)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindBySha256AndRootParentID provides a mock function with given fields: ctx, sha256, rootParentID
func (_m *GenericBlobRepository) FindBySha256AndRootParentID(ctx context.Context, sha256 string, rootParentID int64) (*types.GenericBlob, error) {
ret := _m.Called(ctx, sha256, rootParentID)
if len(ret) == 0 {
panic("no return value specified for FindBySha256AndRootParentID")
}
var r0 *types.GenericBlob
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, int64) (*types.GenericBlob, error)); ok {
return rf(ctx, sha256, rootParentID)
}
if rf, ok := ret.Get(0).(func(context.Context, string, int64) *types.GenericBlob); ok {
r0 = rf(ctx, sha256, rootParentID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.GenericBlob)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok {
r1 = rf(ctx, sha256, rootParentID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// TotalSizeByRootParentID provides a mock function with given fields: ctx, id
func (_m *GenericBlobRepository) TotalSizeByRootParentID(ctx context.Context, id int64) (int64, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for TotalSizeByRootParentID")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (int64, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) int64); ok {
r0 = rf(ctx, id)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewGenericBlobRepository creates a new instance of GenericBlobRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewGenericBlobRepository(t interface {
mock.TestingT
Cleanup(func())
}) *GenericBlobRepository {
mock := &GenericBlobRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,322 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
mock "github.com/stretchr/testify/mock"
)
// ImageRepository is an autogenerated mock type for the ImageRepository type
type ImageRepository struct {
mock.Mock
}
// CountLabelsByParentIDAndRepo provides a mock function with given fields: ctx, parentID, repo, search
func (_m *ImageRepository) CountLabelsByParentIDAndRepo(ctx context.Context, parentID int64, repo string, search string) (int64, error) {
ret := _m.Called(ctx, parentID, repo, search)
if len(ret) == 0 {
panic("no return value specified for CountLabelsByParentIDAndRepo")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (int64, error)); ok {
return rf(ctx, parentID, repo, search)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) int64); ok {
r0 = rf(ctx, parentID, repo, search)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, parentID, repo, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CreateOrUpdate provides a mock function with given fields: ctx, image
func (_m *ImageRepository) CreateOrUpdate(ctx context.Context, image *types.Image) error {
ret := _m.Called(ctx, image)
if len(ret) == 0 {
panic("no return value specified for CreateOrUpdate")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Image) error); ok {
r0 = rf(ctx, image)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteBandwidthStatByRegistryID provides a mock function with given fields: ctx, registryID
func (_m *ImageRepository) DeleteBandwidthStatByRegistryID(ctx context.Context, registryID int64) error {
ret := _m.Called(ctx, registryID)
if len(ret) == 0 {
panic("no return value specified for DeleteBandwidthStatByRegistryID")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, registryID)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteByRegistryID provides a mock function with given fields: ctx, registryID
func (_m *ImageRepository) DeleteByRegistryID(ctx context.Context, registryID int64) error {
ret := _m.Called(ctx, registryID)
if len(ret) == 0 {
panic("no return value specified for DeleteByRegistryID")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, registryID)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteDownloadStatByRegistryID provides a mock function with given fields: ctx, registryID
func (_m *ImageRepository) DeleteDownloadStatByRegistryID(ctx context.Context, registryID int64) error {
ret := _m.Called(ctx, registryID)
if len(ret) == 0 {
panic("no return value specified for DeleteDownloadStatByRegistryID")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, registryID)
} else {
r0 = ret.Error(0)
}
return r0
}
// Get provides a mock function with given fields: ctx, id
func (_m *ImageRepository) Get(ctx context.Context, id int64) (*types.Image, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for Get")
}
var r0 *types.Image
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (*types.Image, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.Image); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Image)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByName provides a mock function with given fields: ctx, registryID, name
func (_m *ImageRepository) GetByName(ctx context.Context, registryID int64, name string) (*types.Image, error) {
ret := _m.Called(ctx, registryID, name)
if len(ret) == 0 {
panic("no return value specified for GetByName")
}
var r0 *types.Image
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*types.Image, error)); ok {
return rf(ctx, registryID, name)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.Image); ok {
r0 = rf(ctx, registryID, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Image)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, registryID, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByRepoAndName provides a mock function with given fields: ctx, parentID, repo, name
func (_m *ImageRepository) GetByRepoAndName(ctx context.Context, parentID int64, repo string, name string) (*types.Image, error) {
ret := _m.Called(ctx, parentID, repo, name)
if len(ret) == 0 {
panic("no return value specified for GetByRepoAndName")
}
var r0 *types.Image
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (*types.Image, error)); ok {
return rf(ctx, parentID, repo, name)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) *types.Image); ok {
r0 = rf(ctx, parentID, repo, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Image)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, parentID, repo, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetLabelsByParentIDAndRepo provides a mock function with given fields: ctx, parentID, repo, limit, offset, search
func (_m *ImageRepository) GetLabelsByParentIDAndRepo(ctx context.Context, parentID int64, repo string, limit int, offset int, search string) ([]string, error) {
ret := _m.Called(ctx, parentID, repo, limit, offset, search)
if len(ret) == 0 {
panic("no return value specified for GetLabelsByParentIDAndRepo")
}
var r0 []string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, int, int, string) ([]string, error)); ok {
return rf(ctx, parentID, repo, limit, offset, search)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, int, int, string) []string); ok {
r0 = rf(ctx, parentID, repo, limit, offset, search)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, int, int, string) error); ok {
r1 = rf(ctx, parentID, repo, limit, offset, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Update provides a mock function with given fields: ctx, artifact
func (_m *ImageRepository) Update(ctx context.Context, artifact *types.Image) error {
ret := _m.Called(ctx, artifact)
if len(ret) == 0 {
panic("no return value specified for Update")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Image) error); ok {
r0 = rf(ctx, artifact)
} else {
r0 = ret.Error(0)
}
return r0
}
// UpdateStatus provides a mock function with given fields: ctx, artifact
func (_m *ImageRepository) UpdateStatus(ctx context.Context, artifact *types.Image) error {
ret := _m.Called(ctx, artifact)
if len(ret) == 0 {
panic("no return value specified for UpdateStatus")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Image) error); ok {
r0 = rf(ctx, artifact)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteByImageNameAndRegID provides a mock function with given fields: ctx, regID, image
func (_m *ImageRepository) DeleteByImageNameAndRegID(ctx context.Context, regID int64, image string) error {
ret := _m.Called(ctx, regID, image)
if len(ret) == 0 {
panic("no return value specified for DeleteByImageNameAndRegID")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) error); ok {
r0 = rf(ctx, regID, image)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteByImageNameIfNoLinkedArtifacts provides a mock function with given fields: ctx, regID, image
func (_m *ImageRepository) DeleteByImageNameIfNoLinkedArtifacts(ctx context.Context, regID int64, image string) error {
ret := _m.Called(ctx, regID, image)
if len(ret) == 0 {
panic("no return value specified for DeleteByImageNameIfNoLinkedArtifacts")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) error); ok {
r0 = rf(ctx, regID, image)
} else {
r0 = ret.Error(0)
}
return r0
}
// NewImageRepository creates a new instance of ImageRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewImageRepository(t interface {
mock.TestingT
Cleanup(func())
}) *ImageRepository {
mock := &ImageRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,211 @@
package mocks
import (
"context"
"github.com/harness/gitness/registry/types"
"github.com/stretchr/testify/mock"
)
// ImageStore is an autogenerated mock type for the ImageStore type
type ImageStore struct {
mock.Mock
}
// Get provides a mock function with given fields: ctx, id
func (m *ImageStore) Get(ctx context.Context, id int64) (*types.Image, error) {
ret := m.Called(ctx, id)
var r0 *types.Image
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.Image); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Image)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByName provides a mock function with given fields: ctx, registryID, name
func (m *ImageStore) GetByName(ctx context.Context, registryID int64, name string) (*types.Image, error) {
ret := m.Called(ctx, registryID, name)
var r0 *types.Image
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.Image); ok {
r0 = rf(ctx, registryID, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Image)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, registryID, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetLabelsByParentIDAndRepo provides a mock function with given fields: ctx, parentID, repo, limit, offset, search
func (m *ImageStore) GetLabelsByParentIDAndRepo(ctx context.Context, parentID int64, repo string, limit int, offset int, search string) ([]string, error) {
ret := m.Called(ctx, parentID, repo, limit, offset, search)
var r0 []string
if rf, ok := ret.Get(0).(func(context.Context, int64, string, int, int, string) []string); ok {
r0 = rf(ctx, parentID, repo, limit, offset, search)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string, int, int, string) error); ok {
r1 = rf(ctx, parentID, repo, limit, offset, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountLabelsByParentIDAndRepo provides a mock function with given fields: ctx, parentID, repo, search
func (m *ImageStore) CountLabelsByParentIDAndRepo(ctx context.Context, parentID int64, repo string, search string) (int64, error) {
ret := m.Called(ctx, parentID, repo, search)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) int64); ok {
r0 = rf(ctx, parentID, repo, search)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, parentID, repo, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByRepoAndName provides a mock function with given fields: ctx, parentID, repo, name
func (m *ImageStore) GetByRepoAndName(ctx context.Context, parentID int64, repo string, name string) (*types.Image, error) {
ret := m.Called(ctx, parentID, repo, name)
var r0 *types.Image
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) *types.Image); ok {
r0 = rf(ctx, parentID, repo, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Image)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, parentID, repo, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CreateOrUpdate provides a mock function with given fields: ctx, image
func (m *ImageStore) CreateOrUpdate(ctx context.Context, image *types.Image) error {
ret := m.Called(ctx, image)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Image) error); ok {
r0 = rf(ctx, image)
} else {
r0 = ret.Error(0)
}
return r0
}
// Update provides a mock function with given fields: ctx, image
func (m *ImageStore) Update(ctx context.Context, image *types.Image) error {
ret := m.Called(ctx, image)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Image) error); ok {
r0 = rf(ctx, image)
} else {
r0 = ret.Error(0)
}
return r0
}
// UpdateStatus provides a mock function with given fields: ctx, image
func (m *ImageStore) UpdateStatus(ctx context.Context, image *types.Image) error {
ret := m.Called(ctx, image)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Image) error); ok {
r0 = rf(ctx, image)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteByRegistryID provides a mock function with given fields: ctx, registryID
func (m *ImageStore) DeleteByRegistryID(ctx context.Context, registryID int64) error {
ret := m.Called(ctx, registryID)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, registryID)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteBandwidthStatByRegistryID provides a mock function with given fields: ctx, registryID
func (m *ImageStore) DeleteBandwidthStatByRegistryID(ctx context.Context, registryID int64) error {
ret := m.Called(ctx, registryID)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, registryID)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteDownloadStatByRegistryID provides a mock function with given fields: ctx, registryID
func (m *ImageStore) DeleteDownloadStatByRegistryID(ctx context.Context, registryID int64) error {
ret := m.Called(ctx, registryID)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, registryID)
} else {
r0 = ret.Error(0)
}
return r0
}

View File

@ -0,0 +1,477 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
digest "github.com/opencontainers/go-digest"
mock "github.com/stretchr/testify/mock"
)
// ManifestRepository is an autogenerated mock type for the ManifestRepository type
type ManifestRepository struct {
mock.Mock
}
// AssociateLayerBlob provides a mock function with given fields: ctx, m, b
func (_m *ManifestRepository) AssociateLayerBlob(ctx context.Context, m *types.Manifest, b *types.Blob) error {
ret := _m.Called(ctx, m, b)
if len(ret) == 0 {
panic("no return value specified for AssociateLayerBlob")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest, *types.Blob) error); ok {
r0 = rf(ctx, m, b)
} else {
r0 = ret.Error(0)
}
return r0
}
// Count provides a mock function with given fields: ctx
func (_m *ManifestRepository) Count(ctx context.Context) (int, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for Count")
}
var r0 int
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (int, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) int); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(int)
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Create provides a mock function with given fields: ctx, m
func (_m *ManifestRepository) Create(ctx context.Context, m *types.Manifest) error {
ret := _m.Called(ctx, m)
if len(ret) == 0 {
panic("no return value specified for Create")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest) error); ok {
r0 = rf(ctx, m)
} else {
r0 = ret.Error(0)
}
return r0
}
// CreateOrFind provides a mock function with given fields: ctx, m
func (_m *ManifestRepository) CreateOrFind(ctx context.Context, m *types.Manifest) error {
ret := _m.Called(ctx, m)
if len(ret) == 0 {
panic("no return value specified for CreateOrFind")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest) error); ok {
r0 = rf(ctx, m)
} else {
r0 = ret.Error(0)
}
return r0
}
// Delete provides a mock function with given fields: ctx, registryID, id
func (_m *ManifestRepository) Delete(ctx context.Context, registryID int64, id int64) error {
ret := _m.Called(ctx, registryID, id)
if len(ret) == 0 {
panic("no return value specified for Delete")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, int64) error); ok {
r0 = rf(ctx, registryID, id)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteManifest provides a mock function with given fields: ctx, repoID, imageName, d
func (_m *ManifestRepository) DeleteManifest(ctx context.Context, repoID int64, imageName string, d digest.Digest) (bool, error) {
ret := _m.Called(ctx, repoID, imageName, d)
if len(ret) == 0 {
panic("no return value specified for DeleteManifest")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, digest.Digest) (bool, error)); ok {
return rf(ctx, repoID, imageName, d)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, digest.Digest) bool); ok {
r0 = rf(ctx, repoID, imageName, d)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, digest.Digest) error); ok {
r1 = rf(ctx, repoID, imageName, d)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DissociateLayerBlob provides a mock function with given fields: ctx, m, b
func (_m *ManifestRepository) DissociateLayerBlob(ctx context.Context, m *types.Manifest, b *types.Blob) error {
ret := _m.Called(ctx, m, b)
if len(ret) == 0 {
panic("no return value specified for DissociateLayerBlob")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest, *types.Blob) error); ok {
r0 = rf(ctx, m, b)
} else {
r0 = ret.Error(0)
}
return r0
}
// FindAll provides a mock function with given fields: ctx
func (_m *ManifestRepository) FindAll(ctx context.Context) (types.Manifests, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for FindAll")
}
var r0 types.Manifests
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (types.Manifests, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) types.Manifests); ok {
r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(types.Manifests)
}
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindManifestByDigest provides a mock function with given fields: ctx, repoID, imageName, _a3
func (_m *ManifestRepository) FindManifestByDigest(ctx context.Context, repoID int64, imageName string, _a3 types.Digest) (*types.Manifest, error) {
ret := _m.Called(ctx, repoID, imageName, _a3)
if len(ret) == 0 {
panic("no return value specified for FindManifestByDigest")
}
var r0 *types.Manifest
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, types.Digest) (*types.Manifest, error)); ok {
return rf(ctx, repoID, imageName, _a3)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, types.Digest) *types.Manifest); ok {
r0 = rf(ctx, repoID, imageName, _a3)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Manifest)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, types.Digest) error); ok {
r1 = rf(ctx, repoID, imageName, _a3)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindManifestByTagName provides a mock function with given fields: ctx, repoID, imageName, tag
func (_m *ManifestRepository) FindManifestByTagName(ctx context.Context, repoID int64, imageName string, tag string) (*types.Manifest, error) {
ret := _m.Called(ctx, repoID, imageName, tag)
if len(ret) == 0 {
panic("no return value specified for FindManifestByTagName")
}
var r0 *types.Manifest
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (*types.Manifest, error)); ok {
return rf(ctx, repoID, imageName, tag)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) *types.Manifest); ok {
r0 = rf(ctx, repoID, imageName, tag)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Manifest)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, repoID, imageName, tag)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindManifestPayloadByTagName provides a mock function with given fields: ctx, parentID, repoKey, imageName, version
func (_m *ManifestRepository) FindManifestPayloadByTagName(ctx context.Context, parentID int64, repoKey string, imageName string, version string) (*types.Payload, error) {
ret := _m.Called(ctx, parentID, repoKey, imageName, version)
if len(ret) == 0 {
panic("no return value specified for FindManifestPayloadByTagName")
}
var r0 *types.Payload
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) (*types.Payload, error)); ok {
return rf(ctx, parentID, repoKey, imageName, version)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) *types.Payload); ok {
r0 = rf(ctx, parentID, repoKey, imageName, version)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Payload)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string) error); ok {
r1 = rf(ctx, parentID, repoKey, imageName, version)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Get provides a mock function with given fields: ctx, manifestID
func (_m *ManifestRepository) Get(ctx context.Context, manifestID int64) (*types.Manifest, error) {
ret := _m.Called(ctx, manifestID)
if len(ret) == 0 {
panic("no return value specified for Get")
}
var r0 *types.Manifest
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (*types.Manifest, error)); ok {
return rf(ctx, manifestID)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.Manifest); ok {
r0 = rf(ctx, manifestID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Manifest)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, manifestID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetManifestPayload provides a mock function with given fields: ctx, parentID, repoKey, imageName, _a4
func (_m *ManifestRepository) GetManifestPayload(ctx context.Context, parentID int64, repoKey string, imageName string, _a4 types.Digest) (*types.Payload, error) {
ret := _m.Called(ctx, parentID, repoKey, imageName, _a4)
if len(ret) == 0 {
panic("no return value specified for GetManifestPayload")
}
var r0 *types.Payload
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, types.Digest) (*types.Payload, error)); ok {
return rf(ctx, parentID, repoKey, imageName, _a4)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, types.Digest) *types.Payload); ok {
r0 = rf(ctx, parentID, repoKey, imageName, _a4)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Payload)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, types.Digest) error); ok {
r1 = rf(ctx, parentID, repoKey, imageName, _a4)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// LayerBlobs provides a mock function with given fields: ctx, m
func (_m *ManifestRepository) LayerBlobs(ctx context.Context, m *types.Manifest) (types.Blobs, error) {
ret := _m.Called(ctx, m)
if len(ret) == 0 {
panic("no return value specified for LayerBlobs")
}
var r0 types.Blobs
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest) (types.Blobs, error)); ok {
return rf(ctx, m)
}
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest) types.Blobs); ok {
r0 = rf(ctx, m)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(types.Blobs)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *types.Manifest) error); ok {
r1 = rf(ctx, m)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListManifestsBySubject provides a mock function with given fields: ctx, repoID, id
func (_m *ManifestRepository) ListManifestsBySubject(ctx context.Context, repoID int64, id int64) (types.Manifests, error) {
ret := _m.Called(ctx, repoID, id)
if len(ret) == 0 {
panic("no return value specified for ListManifestsBySubject")
}
var r0 types.Manifests
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, int64) (types.Manifests, error)); ok {
return rf(ctx, repoID, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, int64) types.Manifests); ok {
r0 = rf(ctx, repoID, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(types.Manifests)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, int64) error); ok {
r1 = rf(ctx, repoID, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListManifestsBySubjectDigest provides a mock function with given fields: ctx, repoID, _a2
func (_m *ManifestRepository) ListManifestsBySubjectDigest(ctx context.Context, repoID int64, _a2 types.Digest) (types.Manifests, error) {
ret := _m.Called(ctx, repoID, _a2)
if len(ret) == 0 {
panic("no return value specified for ListManifestsBySubjectDigest")
}
var r0 types.Manifests
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, types.Digest) (types.Manifests, error)); ok {
return rf(ctx, repoID, _a2)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, types.Digest) types.Manifests); ok {
r0 = rf(ctx, repoID, _a2)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(types.Manifests)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, types.Digest) error); ok {
r1 = rf(ctx, repoID, _a2)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// References provides a mock function with given fields: ctx, m
func (_m *ManifestRepository) References(ctx context.Context, m *types.Manifest) (types.Manifests, error) {
ret := _m.Called(ctx, m)
if len(ret) == 0 {
panic("no return value specified for References")
}
var r0 types.Manifests
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest) (types.Manifests, error)); ok {
return rf(ctx, m)
}
if rf, ok := ret.Get(0).(func(context.Context, *types.Manifest) types.Manifests); ok {
r0 = rf(ctx, m)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(types.Manifests)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *types.Manifest) error); ok {
r1 = rf(ctx, m)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewManifestRepository creates a new instance of ManifestRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewManifestRepository(t interface {
mock.TestingT
Cleanup(func())
}) *ManifestRepository {
mock := &ManifestRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,381 @@
//go:generate mockery --name RegistryMetadataHelper --output . --filename registry_metadata_helper.go --outpkg mocks --with-expecter
package mocks
import (
"context"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
registrytypes "github.com/harness/gitness/registry/types"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/stretchr/testify/mock"
)
// RegistryMetadataHelper is an autogenerated mock type for the RegistryMetadataHelper type
type RegistryMetadataHelper struct {
mock.Mock
}
// GetPermissionChecks provides a mock function with given fields: space, registryIdentifier, permission
func (_m *RegistryMetadataHelper) GetPermissionChecks(space *types.SpaceCore, registryIdentifier string, permission enum.Permission) []types.PermissionCheck {
ret := _m.Called(space, registryIdentifier, permission)
if len(ret) == 0 {
panic("no return value specified for GetPermissionChecks")
}
var r0 []types.PermissionCheck
if rf, ok := ret.Get(0).(func(*types.SpaceCore, string, enum.Permission) []types.PermissionCheck); ok {
r0 = rf(space, registryIdentifier, permission)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]types.PermissionCheck)
}
}
return r0
}
// GetRegistryMetadata provides a mock function with given fields: ctx, registryID
func (_m *RegistryMetadataHelper) GetRegistryMetadata(ctx context.Context, registryID int64) (*registrytypes.Registry, error) {
ret := _m.Called(ctx, registryID)
if len(ret) == 0 {
panic("no return value specified for GetRegistryMetadata")
}
var r0 *registrytypes.Registry
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (*registrytypes.Registry, error)); ok {
return rf(ctx, registryID)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) *registrytypes.Registry); ok {
r0 = rf(ctx, registryID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*registrytypes.Registry)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, registryID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetRegistryMetadataByIdentifier provides a mock function with given fields: ctx, identifier
func (_m *RegistryMetadataHelper) GetRegistryMetadataByIdentifier(ctx context.Context, identifier string) (*registrytypes.Registry, error) {
ret := _m.Called(ctx, identifier)
if len(ret) == 0 {
panic("no return value specified for GetRegistryMetadataByIdentifier")
}
var r0 *registrytypes.Registry
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (*registrytypes.Registry, error)); ok {
return rf(ctx, identifier)
}
if rf, ok := ret.Get(0).(func(context.Context, string) *registrytypes.Registry); ok {
r0 = rf(ctx, identifier)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*registrytypes.Registry)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, identifier)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetRegistryMetadataByParentIDAndIdentifier provides a mock function with given fields: ctx, parentID, identifier
func (_m *RegistryMetadataHelper) GetRegistryMetadataByParentIDAndIdentifier(ctx context.Context, parentID int64, identifier string) (*registrytypes.Registry, error) {
ret := _m.Called(ctx, parentID, identifier)
if len(ret) == 0 {
panic("no return value specified for GetRegistryMetadataByParentIDAndIdentifier")
}
var r0 *registrytypes.Registry
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*registrytypes.Registry, error)); ok {
return rf(ctx, parentID, identifier)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *registrytypes.Registry); ok {
r0 = rf(ctx, parentID, identifier)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*registrytypes.Registry)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, parentID, identifier)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetRegistryMetadataByParentPathAndIdentifier provides a mock function with given fields: ctx, parentPath, identifier
func (_m *RegistryMetadataHelper) GetRegistryMetadataByParentPathAndIdentifier(ctx context.Context, parentPath string, identifier string) (*registrytypes.Registry, error) {
ret := _m.Called(ctx, parentPath, identifier)
if len(ret) == 0 {
panic("no return value specified for GetRegistryMetadataByParentPathAndIdentifier")
}
var r0 *registrytypes.Registry
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (*registrytypes.Registry, error)); ok {
return rf(ctx, parentPath, identifier)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) *registrytypes.Registry); ok {
r0 = rf(ctx, parentPath, identifier)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*registrytypes.Registry)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, parentPath, identifier)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetRegistryMetadataByPath provides a mock function with given fields: ctx, path
func (_m *RegistryMetadataHelper) GetRegistryMetadataByPath(ctx context.Context, path string) (*registrytypes.Registry, error) {
ret := _m.Called(ctx, path)
if len(ret) == 0 {
panic("no return value specified for GetRegistryMetadataByPath")
}
var r0 *registrytypes.Registry
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (*registrytypes.Registry, error)); ok {
return rf(ctx, path)
}
if rf, ok := ret.Get(0).(func(context.Context, string) *registrytypes.Registry); ok {
r0 = rf(ctx, path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*registrytypes.Registry)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, path)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetRegistryRequestBaseInfo provides a mock function with given fields: ctx, parentPath, identifier
func (_m *RegistryMetadataHelper) GetRegistryRequestBaseInfo(ctx context.Context, parentPath string, identifier string) (*registrytypes.RegistryRequestBaseInfo, error) {
ret := _m.Called(ctx, parentPath, identifier)
if len(ret) == 0 {
panic("no return value specified for GetRegistryRequestBaseInfo")
}
var r0 *registrytypes.RegistryRequestBaseInfo
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (*registrytypes.RegistryRequestBaseInfo, error)); ok {
return rf(ctx, parentPath, identifier)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) *registrytypes.RegistryRequestBaseInfo); ok {
r0 = rf(ctx, parentPath, identifier)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*registrytypes.RegistryRequestBaseInfo)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, parentPath, identifier)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetSecretSpaceID provides a mock function with given fields: ctx, secretSpacePath
func (_m *RegistryMetadataHelper) GetSecretSpaceID(ctx context.Context, secretSpacePath *string) (int64, error) {
ret := _m.Called(ctx, secretSpacePath)
if len(ret) == 0 {
panic("no return value specified for GetSecretSpaceID")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *string) (int64, error)); ok {
return rf(ctx, secretSpacePath)
}
if rf, ok := ret.Get(0).(func(context.Context, *string) int64); ok {
r0 = rf(ctx, secretSpacePath)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, *string) error); ok {
r1 = rf(ctx, secretSpacePath)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MapToAPIExtraHeaders provides a mock function with given fields: headers
func (_m *RegistryMetadataHelper) MapToAPIExtraHeaders(headers []types.ExtraHeader) []api.ExtraHeader {
ret := _m.Called(headers)
if len(ret) == 0 {
panic("no return value specified for MapToAPIExtraHeaders")
}
var r0 []api.ExtraHeader
if rf, ok := ret.Get(0).(func([]types.ExtraHeader) []api.ExtraHeader); ok {
r0 = rf(headers)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]api.ExtraHeader)
}
}
return r0
}
// MapToAPIWebhookTriggers provides a mock function with given fields: triggers
func (_m *RegistryMetadataHelper) MapToAPIWebhookTriggers(triggers []enum.WebhookTrigger) []api.Trigger {
ret := _m.Called(triggers)
if len(ret) == 0 {
panic("no return value specified for MapToAPIWebhookTriggers")
}
var r0 []api.Trigger
if rf, ok := ret.Get(0).(func([]enum.WebhookTrigger) []api.Trigger); ok {
r0 = rf(triggers)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]api.Trigger)
}
}
return r0
}
// MapToInternalWebhookTriggers provides a mock function with given fields: triggers
func (_m *RegistryMetadataHelper) MapToInternalWebhookTriggers(triggers []api.Trigger) []enum.WebhookTrigger {
ret := _m.Called(triggers)
if len(ret) == 0 {
panic("no return value specified for MapToInternalWebhookTriggers")
}
var r0 []enum.WebhookTrigger
if rf, ok := ret.Get(0).(func([]api.Trigger) []enum.WebhookTrigger); ok {
r0 = rf(triggers)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]enum.WebhookTrigger)
}
}
return r0
}
// MapToWebhookCore provides a mock function with given fields: ctx, webhookRequest, regInfo
func (_m *RegistryMetadataHelper) MapToWebhookCore(ctx context.Context, webhookRequest api.WebhookRequest, regInfo *registrytypes.RegistryRequestBaseInfo) (*types.WebhookCore, error) {
ret := _m.Called(ctx, webhookRequest, regInfo)
if len(ret) == 0 {
panic("no return value specified for MapToWebhookCore")
}
var r0 *types.WebhookCore
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, api.WebhookRequest, *registrytypes.RegistryRequestBaseInfo) (*types.WebhookCore, error)); ok {
return rf(ctx, webhookRequest, regInfo)
}
if rf, ok := ret.Get(0).(func(context.Context, api.WebhookRequest, *registrytypes.RegistryRequestBaseInfo) *types.WebhookCore); ok {
r0 = rf(ctx, webhookRequest, regInfo)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.WebhookCore)
}
}
if rf, ok := ret.Get(1).(func(context.Context, api.WebhookRequest, *registrytypes.RegistryRequestBaseInfo) error); ok {
r1 = rf(ctx, webhookRequest, regInfo)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MapToWebhookResponseEntity provides a mock function with given fields: ctx, webhook
func (_m *RegistryMetadataHelper) MapToWebhookResponseEntity(ctx context.Context, webhook *types.WebhookCore) (*api.Webhook, error) {
ret := _m.Called(ctx, webhook)
if len(ret) == 0 {
panic("no return value specified for MapToWebhookResponseEntity")
}
var r0 *api.Webhook
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *types.WebhookCore) (*api.Webhook, error)); ok {
return rf(ctx, webhook)
}
if rf, ok := ret.Get(0).(func(context.Context, *types.WebhookCore) *api.Webhook); ok {
r0 = rf(ctx, webhook)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*api.Webhook)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *types.WebhookCore) error); ok {
r1 = rf(ctx, webhook)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewRegistryMetadataHelper creates a new instance of RegistryMetadataHelper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewRegistryMetadataHelper(t interface {
mock.TestingT
Cleanup(func())
}) *RegistryMetadataHelper {
mock := &RegistryMetadataHelper{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,292 @@
// Code generated by testify. DO NOT EDIT.
package mocks
import (
"context"
"github.com/harness/gitness/registry/app/store"
"github.com/harness/gitness/registry/types"
"github.com/stretchr/testify/mock"
)
// FetchUpstreamProxyIDs provides a mock function
func (m *RegistryRepository) FetchUpstreamProxyIDs(ctx context.Context, repokeys []string, parentID int64) ([]int64, error) {
ret := m.Called(ctx, repokeys, parentID)
var r0 []int64
if rf, ok := ret.Get(0).(func(context.Context, []string, int64) []int64); ok {
r0 = rf(ctx, repokeys, parentID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]int64)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, []string, int64) error); ok {
r1 = rf(ctx, repokeys, parentID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// RegistryRepository is a mock of RegistryRepository interface.
type RegistryRepository struct {
mock.Mock
}
// GetAll provides a mock function
func (m *RegistryRepository) GetAll(ctx context.Context, parentID int64, packageTypes []string, sortByField string, sortByOrder string, limit int, offset int, search string, repoType string, recursive bool) (*[]store.RegistryMetadata, error) {
ret := m.Called(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search, repoType, recursive)
var r0 *[]store.RegistryMetadata
if rf, ok := ret.Get(0).(func(context.Context, int64, []string, string, string, int, int, string, string, bool) *[]store.RegistryMetadata); ok {
r0 = rf(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search, repoType, recursive)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]store.RegistryMetadata)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, []string, string, string, int, int, string, string, bool) error); ok {
r1 = rf(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search, repoType, recursive)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FetchUpstreamProxyKeys provides a mock function
func (m *RegistryRepository) FetchUpstreamProxyKeys(ctx context.Context, ids []int64) ([]string, error) {
ret := m.Called(ctx, ids)
var r0 []string
if rf, ok := ret.Get(0).(func(context.Context, []int64) []string); ok {
r0 = rf(ctx, ids)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok {
r1 = rf(ctx, ids)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Get provides a mock function
func (m *RegistryRepository) Get(ctx context.Context, id int64) (*types.Registry, error) {
ret := m.Called(ctx, id)
var r0 *types.Registry
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.Registry); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Registry)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByIDIn provides a mock function
func (m *RegistryRepository) GetByIDIn(ctx context.Context, ids []int64) (*[]types.Registry, error) {
ret := m.Called(ctx, ids)
var r0 *[]types.Registry
if rf, ok := ret.Get(0).(func(context.Context, []int64) *[]types.Registry); ok {
r0 = rf(ctx, ids)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.Registry)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok {
r1 = rf(ctx, ids)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByParentIDAndName provides a mock function
func (m *RegistryRepository) GetByParentIDAndName(ctx context.Context, parentID int64, name string) (*types.Registry, error) {
ret := m.Called(ctx, parentID, name)
var r0 *types.Registry
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.Registry); ok {
r0 = rf(ctx, parentID, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Registry)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, parentID, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByRootParentIDAndName provides a mock function
func (m *RegistryRepository) GetByRootParentIDAndName(ctx context.Context, parentID int64, name string) (*types.Registry, error) {
ret := m.Called(ctx, parentID, name)
var r0 *types.Registry
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.Registry); ok {
r0 = rf(ctx, parentID, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Registry)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, parentID, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Create provides a mock function
func (m *RegistryRepository) Create(ctx context.Context, registry *types.Registry) (int64, error) {
ret := m.Called(ctx, registry)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context, *types.Registry) int64); ok {
r0 = rf(ctx, registry)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *types.Registry) error); ok {
r1 = rf(ctx, registry)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Delete provides a mock function
func (m *RegistryRepository) Delete(ctx context.Context, parentID int64, name string) error {
ret := m.Called(ctx, parentID, name)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) error); ok {
r0 = rf(ctx, parentID, name)
} else {
r0 = ret.Error(0)
}
return r0
}
// Update provides a mock function
func (m *RegistryRepository) Update(ctx context.Context, registry *types.Registry) error {
ret := m.Called(ctx, registry)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Registry) error); ok {
r0 = rf(ctx, registry)
} else {
r0 = ret.Error(0)
}
return r0
}
// CountAll provides a mock function
func (m *RegistryRepository) CountAll(ctx context.Context, parentID int64, packageTypes []string, search string, repoType string) (int64, error) {
ret := m.Called(ctx, parentID, packageTypes, search, repoType)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context, int64, []string, string, string) int64); ok {
r0 = rf(ctx, parentID, packageTypes, search, repoType)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, []string, string, string) error); ok {
r1 = rf(ctx, parentID, packageTypes, search, repoType)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Count provides a mock function
func (m *RegistryRepository) Count(ctx context.Context) (int64, error) {
ret := m.Called(ctx)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context) int64); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FetchRegistriesIDByUpstreamProxyID provides a mock function
func (m *RegistryRepository) FetchRegistriesIDByUpstreamProxyID(ctx context.Context, upstreamProxyID string, rootParentID int64) ([]int64, error) {
ret := m.Called(ctx, upstreamProxyID, rootParentID)
var r0 []int64
if rf, ok := ret.Get(0).(func(context.Context, string, int64) []int64); ok {
r0 = rf(ctx, upstreamProxyID, rootParentID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]int64)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok {
r1 = rf(ctx, upstreamProxyID, rootParentID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -0,0 +1,34 @@
package mocks
import (
"context"
registryevents "github.com/harness/gitness/registry/app/events"
"github.com/stretchr/testify/mock"
)
// Reporter is a mock implementation of registryevents.Reporter
type Reporter struct {
mock.Mock
}
func NewReporter() *Reporter {
return &Reporter{}
}
// Report provides a mock function
func (m *Reporter) Report(ctx context.Context, event interface{}) error {
args := m.Called(ctx, event)
return args.Error(0)
}
// ArtifactCreated provides a mock function
func (m *Reporter) ArtifactCreated(ctx context.Context, payload *registryevents.ArtifactCreatedPayload) {
m.Called(ctx, payload)
}
// ArtifactDeleted provides a mock function
func (m *Reporter) ArtifactDeleted(ctx context.Context, payload *registryevents.ArtifactDeletedPayload) {
m.Called(ctx, payload)
}

View File

@ -0,0 +1,130 @@
// Code generated by testify. DO NOT EDIT.
package mocks
import (
"context"
"github.com/harness/gitness/types"
"github.com/stretchr/testify/mock"
)
// SpaceFinder is a mock of SpaceFinder interface.
type SpaceFinder struct {
mock.Mock
}
// Find provides a mock function
func (m *SpaceFinder) Find(ctx context.Context, id int64) (*types.SpaceCore, error) {
ret := m.Called(ctx, id)
var r0 *types.SpaceCore
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.SpaceCore); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.SpaceCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindByRef provides a mock function
func (m *SpaceFinder) FindByID(ctx context.Context, id int64) (*types.SpaceCore, error) {
ret := m.Called(ctx, id)
var r0 *types.SpaceCore
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.SpaceCore); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.SpaceCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (m *SpaceFinder) FindByRef(ctx context.Context, ref string) (*types.SpaceCore, error) {
ret := m.Called(ctx, ref)
var r0 *types.SpaceCore
if rf, ok := ret.Get(0).(func(context.Context, string) *types.SpaceCore); ok {
r0 = rf(ctx, ref)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.SpaceCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, ref)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindByPath provides a mock function
func (m *SpaceFinder) FindByPath(ctx context.Context, path string) (*types.SpaceCore, error) {
ret := m.Called(ctx, path)
var r0 *types.SpaceCore
if rf, ok := ret.Get(0).(func(context.Context, string) *types.SpaceCore); ok {
r0 = rf(ctx, path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.SpaceCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, path)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindByIdentifier provides a mock function
func (m *SpaceFinder) FindByIdentifier(ctx context.Context, identifier string) (*types.SpaceCore, error) {
ret := m.Called(ctx, identifier)
var r0 *types.SpaceCore
if rf, ok := ret.Get(0).(func(context.Context, string) *types.SpaceCore); ok {
r0 = rf(ctx, identifier)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.SpaceCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, identifier)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -0,0 +1,102 @@
package mocks
import (
"context"
"github.com/harness/gitness/types"
"github.com/stretchr/testify/mock"
)
// SpacePathStore is a mock of SpacePathStore interface.
type SpacePathStore struct {
mock.Mock
}
// FindByPath provides a mock function
func (m *SpacePathStore) FindByPath(ctx context.Context, path string) (*types.SpacePath, error) {
ret := m.Called(ctx, path)
var r0 *types.SpacePath
if rf, ok := ret.Get(0).(func(context.Context, string) *types.SpacePath); ok {
r0 = rf(ctx, path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.SpacePath)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, path)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindPrimaryBySpaceID provides a mock function
func (m *SpacePathStore) FindPrimaryBySpaceID(ctx context.Context, spaceID int64) (*types.SpacePath, error) {
ret := m.Called(ctx, spaceID)
var r0 *types.SpacePath
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.SpacePath); ok {
r0 = rf(ctx, spaceID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.SpacePath)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, spaceID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// InsertSegment provides a mock function
func (m *SpacePathStore) InsertSegment(ctx context.Context, segment *types.SpacePathSegment) error {
ret := m.Called(ctx, segment)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.SpacePathSegment) error); ok {
r0 = rf(ctx, segment)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeletePrimarySegment provides a mock function
func (m *SpacePathStore) DeletePrimarySegment(ctx context.Context, spaceID int64) error {
ret := m.Called(ctx, spaceID)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, spaceID)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeletePathsAndDescendandPaths provides a mock function
func (m *SpacePathStore) DeletePathsAndDescendandPaths(ctx context.Context, spaceID int64) error {
ret := m.Called(ctx, spaceID)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
r0 = rf(ctx, spaceID)
} else {
r0 = ret.Error(0)
}
return r0
}

View File

@ -0,0 +1,306 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
io "io"
driver "github.com/harness/gitness/registry/app/driver"
mock "github.com/stretchr/testify/mock"
)
// StorageDriver is an autogenerated mock type for the StorageDriver type
type StorageDriver struct {
mock.Mock
}
// Delete provides a mock function with given fields: ctx, path
func (_m *StorageDriver) Delete(ctx context.Context, path string) error {
ret := _m.Called(ctx, path)
if len(ret) == 0 {
panic("no return value specified for Delete")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
r0 = rf(ctx, path)
} else {
r0 = ret.Error(0)
}
return r0
}
// GetContent provides a mock function with given fields: ctx, path
func (_m *StorageDriver) GetContent(ctx context.Context, path string) ([]byte, error) {
ret := _m.Called(ctx, path)
if len(ret) == 0 {
panic("no return value specified for GetContent")
}
var r0 []byte
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) ([]byte, error)); ok {
return rf(ctx, path)
}
if rf, ok := ret.Get(0).(func(context.Context, string) []byte); ok {
r0 = rf(ctx, path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]byte)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, path)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// List provides a mock function with given fields: ctx, path
func (_m *StorageDriver) List(ctx context.Context, path string) ([]string, error) {
ret := _m.Called(ctx, path)
if len(ret) == 0 {
panic("no return value specified for List")
}
var r0 []string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok {
return rf(ctx, path)
}
if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok {
r0 = rf(ctx, path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, path)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Move provides a mock function with given fields: ctx, sourcePath, destPath
func (_m *StorageDriver) Move(ctx context.Context, sourcePath string, destPath string) error {
ret := _m.Called(ctx, sourcePath, destPath)
if len(ret) == 0 {
panic("no return value specified for Move")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
r0 = rf(ctx, sourcePath, destPath)
} else {
r0 = ret.Error(0)
}
return r0
}
// Name provides a mock function with no fields
func (_m *StorageDriver) Name() string {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Name")
}
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// PutContent provides a mock function with given fields: ctx, path, content
func (_m *StorageDriver) PutContent(ctx context.Context, path string, content []byte) error {
ret := _m.Called(ctx, path, content)
if len(ret) == 0 {
panic("no return value specified for PutContent")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, []byte) error); ok {
r0 = rf(ctx, path, content)
} else {
r0 = ret.Error(0)
}
return r0
}
// Reader provides a mock function with given fields: ctx, path, offset
func (_m *StorageDriver) Reader(ctx context.Context, path string, offset int64) (io.ReadCloser, error) {
ret := _m.Called(ctx, path, offset)
if len(ret) == 0 {
panic("no return value specified for Reader")
}
var r0 io.ReadCloser
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, int64) (io.ReadCloser, error)); ok {
return rf(ctx, path, offset)
}
if rf, ok := ret.Get(0).(func(context.Context, string, int64) io.ReadCloser); ok {
r0 = rf(ctx, path, offset)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(io.ReadCloser)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok {
r1 = rf(ctx, path, offset)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// RedirectURL provides a mock function with given fields: ctx, method, path
func (_m *StorageDriver) RedirectURL(ctx context.Context, method string, path string) (string, error) {
ret := _m.Called(ctx, method, path)
if len(ret) == 0 {
panic("no return value specified for RedirectURL")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (string, error)); ok {
return rf(ctx, method, path)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) string); ok {
r0 = rf(ctx, method, path)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, method, path)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Stat provides a mock function with given fields: ctx, path
func (_m *StorageDriver) Stat(ctx context.Context, path string) (driver.FileInfo, error) {
ret := _m.Called(ctx, path)
if len(ret) == 0 {
panic("no return value specified for Stat")
}
var r0 driver.FileInfo
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (driver.FileInfo, error)); ok {
return rf(ctx, path)
}
if rf, ok := ret.Get(0).(func(context.Context, string) driver.FileInfo); ok {
r0 = rf(ctx, path)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(driver.FileInfo)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, path)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Walk provides a mock function with given fields: ctx, path, f, options
func (_m *StorageDriver) Walk(ctx context.Context, path string, f driver.WalkFn, options ...func(*driver.WalkOptions)) error {
_va := make([]interface{}, len(options))
for _i := range options {
_va[_i] = options[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, path, f)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for Walk")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, driver.WalkFn, ...func(*driver.WalkOptions)) error); ok {
r0 = rf(ctx, path, f, options...)
} else {
r0 = ret.Error(0)
}
return r0
}
// Writer provides a mock function with given fields: ctx, path, a
func (_m *StorageDriver) Writer(ctx context.Context, path string, a bool) (driver.FileWriter, error) {
ret := _m.Called(ctx, path, a)
if len(ret) == 0 {
panic("no return value specified for Writer")
}
var r0 driver.FileWriter
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, bool) (driver.FileWriter, error)); ok {
return rf(ctx, path, a)
}
if rf, ok := ret.Get(0).(func(context.Context, string, bool) driver.FileWriter); ok {
r0 = rf(ctx, path, a)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(driver.FileWriter)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, bool) error); ok {
r1 = rf(ctx, path, a)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewStorageDriver creates a new instance of StorageDriver. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewStorageDriver(t interface {
mock.TestingT
Cleanup(func())
}) *StorageDriver {
mock := &StorageDriver{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,49 @@
// Code generated by mockery v2.20.0. DO NOT EDIT.
package mocks
import (
"context"
mock "github.com/stretchr/testify/mock"
)
// StreamProducer is an autogenerated mock type for the StreamProducer type
type StreamProducer struct {
mock.Mock
}
// Send provides a mock function with given fields: ctx, topic, payload
func (m *StreamProducer) Send(ctx context.Context, topic string, payload map[string]interface{}) (string, error) {
ret := m.Called(ctx, topic, payload)
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string, map[string]interface{}) string); ok {
r0 = rf(ctx, topic, payload)
} else {
r0 = ret.Get(0).(string)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string, map[string]interface{}) error); ok {
r1 = rf(ctx, topic, payload)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Close provides a mock function with given fields:
func (m *StreamProducer) Close() error {
ret := m.Called()
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}

View File

@ -0,0 +1,578 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
mock "github.com/stretchr/testify/mock"
)
// TagRepository is an autogenerated mock type for the TagRepository type
type TagRepository struct {
mock.Mock
}
// CountAllArtifactsByParentID provides a mock function with given fields: ctx, parentID, registryIDs, search, latestVersion, packageTypes
func (_m *TagRepository) CountAllArtifactsByParentID(ctx context.Context, parentID int64, registryIDs *[]string, search string, latestVersion bool, packageTypes []string) (int64, error) {
ret := _m.Called(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
if len(ret) == 0 {
panic("no return value specified for CountAllArtifactsByParentID")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, bool, []string) (int64, error)); ok {
return rf(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, bool, []string) int64); ok {
r0 = rf(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, *[]string, string, bool, []string) error); ok {
r1 = rf(ctx, parentID, registryIDs, search, latestVersion, packageTypes)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountAllArtifactsByRepo provides a mock function with given fields: ctx, parentID, repoKey, search, labels
func (_m *TagRepository) CountAllArtifactsByRepo(ctx context.Context, parentID int64, repoKey string, search string, labels []string) (int64, error) {
ret := _m.Called(ctx, parentID, repoKey, search, labels)
if len(ret) == 0 {
panic("no return value specified for CountAllArtifactsByRepo")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, []string) (int64, error)); ok {
return rf(ctx, parentID, repoKey, search, labels)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, []string) int64); ok {
r0 = rf(ctx, parentID, repoKey, search, labels)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, []string) error); ok {
r1 = rf(ctx, parentID, repoKey, search, labels)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountAllTagsByRepoAndImage provides a mock function with given fields: ctx, parentID, repoKey, image, search
func (_m *TagRepository) CountAllTagsByRepoAndImage(ctx context.Context, parentID int64, repoKey string, image string, search string) (int64, error) {
ret := _m.Called(ctx, parentID, repoKey, image, search)
if len(ret) == 0 {
panic("no return value specified for CountAllTagsByRepoAndImage")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) (int64, error)); ok {
return rf(ctx, parentID, repoKey, image, search)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) int64); ok {
r0 = rf(ctx, parentID, repoKey, image, search)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string) error); ok {
r1 = rf(ctx, parentID, repoKey, image, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CreateOrUpdate provides a mock function with given fields: ctx, t
func (_m *TagRepository) CreateOrUpdate(ctx context.Context, t *types.Tag) error {
ret := _m.Called(ctx, t)
if len(ret) == 0 {
panic("no return value specified for CreateOrUpdate")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.Tag) error); ok {
r0 = rf(ctx, t)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteTag provides a mock function with given fields: ctx, registryID, imageName, name
func (_m *TagRepository) DeleteTag(ctx context.Context, registryID int64, imageName string, name string) error {
ret := _m.Called(ctx, registryID, imageName, name)
if len(ret) == 0 {
panic("no return value specified for DeleteTag")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) error); ok {
r0 = rf(ctx, registryID, imageName, name)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteTagByManifestID provides a mock function with given fields: ctx, repoID, manifestID
func (_m *TagRepository) DeleteTagByManifestID(ctx context.Context, repoID int64, manifestID int64) (bool, error) {
ret := _m.Called(ctx, repoID, manifestID)
if len(ret) == 0 {
panic("no return value specified for DeleteTagByManifestID")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, int64) (bool, error)); ok {
return rf(ctx, repoID, manifestID)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, int64) bool); ok {
r0 = rf(ctx, repoID, manifestID)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, int64) error); ok {
r1 = rf(ctx, repoID, manifestID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DeleteTagByName provides a mock function with given fields: ctx, repoID, name
func (_m *TagRepository) DeleteTagByName(ctx context.Context, repoID int64, name string) (bool, error) {
ret := _m.Called(ctx, repoID, name)
if len(ret) == 0 {
panic("no return value specified for DeleteTagByName")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (bool, error)); ok {
return rf(ctx, repoID, name)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) bool); ok {
r0 = rf(ctx, repoID, name)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, repoID, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DeleteTagsByImageName provides a mock function with given fields: ctx, registryID, imageName
func (_m *TagRepository) DeleteTagsByImageName(ctx context.Context, registryID int64, imageName string) error {
ret := _m.Called(ctx, registryID, imageName)
if len(ret) == 0 {
panic("no return value specified for DeleteTagsByImageName")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) error); ok {
r0 = rf(ctx, registryID, imageName)
} else {
r0 = ret.Error(0)
}
return r0
}
// FindTag provides a mock function with given fields: ctx, repoID, imageName, name
func (_m *TagRepository) FindTag(ctx context.Context, repoID int64, imageName string, name string) (*types.Tag, error) {
ret := _m.Called(ctx, repoID, imageName, name)
if len(ret) == 0 {
panic("no return value specified for FindTag")
}
var r0 *types.Tag
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (*types.Tag, error)); ok {
return rf(ctx, repoID, imageName, name)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) *types.Tag); ok {
r0 = rf(ctx, repoID, imageName, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Tag)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, repoID, imageName, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAllArtifactsByParentID provides a mock function with given fields: ctx, parentID, registryIDs, sortByField, sortByOrder, limit, offset, search, latestVersion, packageTypes
func (_m *TagRepository) GetAllArtifactsByParentID(ctx context.Context, parentID int64, registryIDs *[]string, sortByField string, sortByOrder string, limit int, offset int, search string, latestVersion bool, packageTypes []string) (*[]types.ArtifactMetadata, error) {
ret := _m.Called(ctx, parentID, registryIDs, sortByField, sortByOrder, limit, offset, search, latestVersion, packageTypes)
if len(ret) == 0 {
panic("no return value specified for GetAllArtifactsByParentID")
}
var r0 *[]types.ArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, string, int, int, string, bool, []string) (*[]types.ArtifactMetadata, error)); ok {
return rf(ctx, parentID, registryIDs, sortByField, sortByOrder, limit, offset, search, latestVersion, packageTypes)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, *[]string, string, string, int, int, string, bool, []string) *[]types.ArtifactMetadata); ok {
r0 = rf(ctx, parentID, registryIDs, sortByField, sortByOrder, limit, offset, search, latestVersion, packageTypes)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.ArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, *[]string, string, string, int, int, string, bool, []string) error); ok {
r1 = rf(ctx, parentID, registryIDs, sortByField, sortByOrder, limit, offset, search, latestVersion, packageTypes)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAllArtifactsByRepo provides a mock function with given fields: ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels
func (_m *TagRepository) GetAllArtifactsByRepo(ctx context.Context, parentID int64, repoKey string, sortByField string, sortByOrder string, limit int, offset int, search string, labels []string) (*[]types.ArtifactMetadata, error) {
ret := _m.Called(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
if len(ret) == 0 {
panic("no return value specified for GetAllArtifactsByRepo")
}
var r0 *[]types.ArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, int, int, string, []string) (*[]types.ArtifactMetadata, error)); ok {
return rf(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, int, int, string, []string) *[]types.ArtifactMetadata); ok {
r0 = rf(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.ArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string, int, int, string, []string) error); ok {
r1 = rf(ctx, parentID, repoKey, sortByField, sortByOrder, limit, offset, search, labels)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAllTagsByRepoAndImage provides a mock function with given fields: ctx, parentID, repoKey, image, sortByField, sortByOrder, limit, offset, search
func (_m *TagRepository) GetAllTagsByRepoAndImage(ctx context.Context, parentID int64, repoKey string, image string, sortByField string, sortByOrder string, limit int, offset int, search string) (*[]types.TagMetadata, error) {
ret := _m.Called(ctx, parentID, repoKey, image, sortByField, sortByOrder, limit, offset, search)
if len(ret) == 0 {
panic("no return value specified for GetAllTagsByRepoAndImage")
}
var r0 *[]types.TagMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, string, int, int, string) (*[]types.TagMetadata, error)); ok {
return rf(ctx, parentID, repoKey, image, sortByField, sortByOrder, limit, offset, search)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string, string, int, int, string) *[]types.TagMetadata); ok {
r0 = rf(ctx, parentID, repoKey, image, sortByField, sortByOrder, limit, offset, search)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.TagMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string, string, int, int, string) error); ok {
r1 = rf(ctx, parentID, repoKey, image, sortByField, sortByOrder, limit, offset, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetLatestTag provides a mock function with given fields: ctx, repoID, imageName
func (_m *TagRepository) GetLatestTag(ctx context.Context, repoID int64, imageName string) (*types.Tag, error) {
ret := _m.Called(ctx, repoID, imageName)
if len(ret) == 0 {
panic("no return value specified for GetLatestTag")
}
var r0 *types.Tag
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*types.Tag, error)); ok {
return rf(ctx, repoID, imageName)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.Tag); ok {
r0 = rf(ctx, repoID, imageName)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Tag)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, repoID, imageName)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetLatestTagMetadata provides a mock function with given fields: ctx, parentID, repoKey, imageName
func (_m *TagRepository) GetLatestTagMetadata(ctx context.Context, parentID int64, repoKey string, imageName string) (*types.ArtifactMetadata, error) {
ret := _m.Called(ctx, parentID, repoKey, imageName)
if len(ret) == 0 {
panic("no return value specified for GetLatestTagMetadata")
}
var r0 *types.ArtifactMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (*types.ArtifactMetadata, error)); ok {
return rf(ctx, parentID, repoKey, imageName)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) *types.ArtifactMetadata); ok {
r0 = rf(ctx, parentID, repoKey, imageName)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ArtifactMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, parentID, repoKey, imageName)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetLatestTagName provides a mock function with given fields: ctx, parentID, repoKey, imageName
func (_m *TagRepository) GetLatestTagName(ctx context.Context, parentID int64, repoKey string, imageName string) (string, error) {
ret := _m.Called(ctx, parentID, repoKey, imageName)
if len(ret) == 0 {
panic("no return value specified for GetLatestTagName")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (string, error)); ok {
return rf(ctx, parentID, repoKey, imageName)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) string); ok {
r0 = rf(ctx, parentID, repoKey, imageName)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, parentID, repoKey, imageName)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetTagDetail provides a mock function with given fields: ctx, repoID, imageName, name
func (_m *TagRepository) GetTagDetail(ctx context.Context, repoID int64, imageName string, name string) (*types.TagDetail, error) {
ret := _m.Called(ctx, repoID, imageName, name)
if len(ret) == 0 {
panic("no return value specified for GetTagDetail")
}
var r0 *types.TagDetail
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) (*types.TagDetail, error)); ok {
return rf(ctx, repoID, imageName, name)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string) *types.TagDetail); ok {
r0 = rf(ctx, repoID, imageName, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.TagDetail)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string) error); ok {
r1 = rf(ctx, repoID, imageName, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetTagMetadata provides a mock function with given fields: ctx, parentID, repoKey, imageName, name
func (_m *TagRepository) GetTagMetadata(ctx context.Context, parentID int64, repoKey string, imageName string, name string) (*types.TagMetadata, error) {
ret := _m.Called(ctx, parentID, repoKey, imageName, name)
if len(ret) == 0 {
panic("no return value specified for GetTagMetadata")
}
var r0 *types.TagMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) (*types.TagMetadata, error)); ok {
return rf(ctx, parentID, repoKey, imageName, name)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, string) *types.TagMetadata); ok {
r0 = rf(ctx, parentID, repoKey, imageName, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.TagMetadata)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, string) error); ok {
r1 = rf(ctx, parentID, repoKey, imageName, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// HasTagsAfterName provides a mock function with given fields: ctx, repoID, filters
func (_m *TagRepository) HasTagsAfterName(ctx context.Context, repoID int64, filters types.FilterParams) (bool, error) {
ret := _m.Called(ctx, repoID, filters)
if len(ret) == 0 {
panic("no return value specified for HasTagsAfterName")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, types.FilterParams) (bool, error)); ok {
return rf(ctx, repoID, filters)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, types.FilterParams) bool); ok {
r0 = rf(ctx, repoID, filters)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, types.FilterParams) error); ok {
r1 = rf(ctx, repoID, filters)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// LockTagByNameForUpdate provides a mock function with given fields: ctx, repoID, name
func (_m *TagRepository) LockTagByNameForUpdate(ctx context.Context, repoID int64, name string) (bool, error) {
ret := _m.Called(ctx, repoID, name)
if len(ret) == 0 {
panic("no return value specified for LockTagByNameForUpdate")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (bool, error)); ok {
return rf(ctx, repoID, name)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) bool); ok {
r0 = rf(ctx, repoID, name)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, repoID, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// TagsPaginated provides a mock function with given fields: ctx, repoID, image, filters
func (_m *TagRepository) TagsPaginated(ctx context.Context, repoID int64, image string, filters types.FilterParams) ([]*types.Tag, error) {
ret := _m.Called(ctx, repoID, image, filters)
if len(ret) == 0 {
panic("no return value specified for TagsPaginated")
}
var r0 []*types.Tag
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string, types.FilterParams) ([]*types.Tag, error)); ok {
return rf(ctx, repoID, image, filters)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string, types.FilterParams) []*types.Tag); ok {
r0 = rf(ctx, repoID, image, filters)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*types.Tag)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string, types.FilterParams) error); ok {
r1 = rf(ctx, repoID, image, filters)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewTagRepository creates a new instance of TagRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewTagRepository(t interface {
mock.TestingT
Cleanup(func())
}) *TagRepository {
mock := &TagRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,33 @@
// Code generated by mockery v2.14.0. DO NOT EDIT.
package mocks
import (
"context"
"github.com/stretchr/testify/mock"
)
// Transaction is an autogenerated mock type for the Transaction type
type Transaction struct {
mock.Mock
}
// WithTx provides a mock function with given fields: ctx, fn, options
func (m *Transaction) WithTx(ctx context.Context, fn func(context.Context) error, options ...interface{}) error {
var args []interface{}
args = append(args, ctx, fn)
for _, opt := range options {
args = append(args, opt)
}
ret := m.Called(args...)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, func(context.Context) error, ...interface{}) error); ok {
r0 = rf(ctx, fn, options...)
} else {
r0 = ret.Error(0)
}
return r0
}

View File

@ -0,0 +1,38 @@
// Code generated by mockery. DO NOT EDIT.
package mocks
import (
"context"
"github.com/stretchr/testify/mock"
)
// Transactor is a mock of dbtx.Transactor interface.
type Transactor struct {
mock.Mock
}
// WithTx provides a mock function
func (m *Transactor) WithTx(ctx context.Context, fn func(context.Context) error, opts ...interface{}) error {
args := m.Called(ctx, fn, opts)
return args.Error(0)
}
// BeginTx provides a mock function
func (m *Transactor) BeginTx(ctx context.Context) (context.Context, error) {
args := m.Called(ctx)
return args.Get(0).(context.Context), args.Error(1)
}
// CommitTx provides a mock function
func (m *Transactor) CommitTx(ctx context.Context) error {
args := m.Called(ctx)
return args.Error(0)
}
// RollbackTx provides a mock function
func (m *Transactor) RollbackTx(ctx context.Context) error {
args := m.Called(ctx)
return args.Error(0)
}

View File

@ -0,0 +1,242 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
types "github.com/harness/gitness/registry/types"
mock "github.com/stretchr/testify/mock"
)
// UpstreamProxyConfigRepository is an autogenerated mock type for the UpstreamProxyConfigRepository type
type UpstreamProxyConfigRepository struct {
mock.Mock
}
// CountAll provides a mock function with given fields: ctx, parentID, packageTypes, search
func (_m *UpstreamProxyConfigRepository) CountAll(ctx context.Context, parentID string, packageTypes []string, search string) (int64, error) {
ret := _m.Called(ctx, parentID, packageTypes, search)
if len(ret) == 0 {
panic("no return value specified for CountAll")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, []string, string) (int64, error)); ok {
return rf(ctx, parentID, packageTypes, search)
}
if rf, ok := ret.Get(0).(func(context.Context, string, []string, string) int64); ok {
r0 = rf(ctx, parentID, packageTypes, search)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, string, []string, string) error); ok {
r1 = rf(ctx, parentID, packageTypes, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Create provides a mock function with given fields: ctx, upstreamproxyRecord
func (_m *UpstreamProxyConfigRepository) Create(ctx context.Context, upstreamproxyRecord *types.UpstreamProxyConfig) (int64, error) {
ret := _m.Called(ctx, upstreamproxyRecord)
if len(ret) == 0 {
panic("no return value specified for Create")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *types.UpstreamProxyConfig) (int64, error)); ok {
return rf(ctx, upstreamproxyRecord)
}
if rf, ok := ret.Get(0).(func(context.Context, *types.UpstreamProxyConfig) int64); ok {
r0 = rf(ctx, upstreamproxyRecord)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, *types.UpstreamProxyConfig) error); ok {
r1 = rf(ctx, upstreamproxyRecord)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Delete provides a mock function with given fields: ctx, parentID, repoKey
func (_m *UpstreamProxyConfigRepository) Delete(ctx context.Context, parentID int64, repoKey string) error {
ret := _m.Called(ctx, parentID, repoKey)
if len(ret) == 0 {
panic("no return value specified for Delete")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) error); ok {
r0 = rf(ctx, parentID, repoKey)
} else {
r0 = ret.Error(0)
}
return r0
}
// Get provides a mock function with given fields: ctx, id
func (_m *UpstreamProxyConfigRepository) Get(ctx context.Context, id int64) (*types.UpstreamProxy, error) {
ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for Get")
}
var r0 *types.UpstreamProxy
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64) (*types.UpstreamProxy, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.UpstreamProxy); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.UpstreamProxy)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAll provides a mock function with given fields: ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search
func (_m *UpstreamProxyConfigRepository) GetAll(ctx context.Context, parentID int64, packageTypes []string, sortByField string, sortByOrder string, limit int, offset int, search string) (*[]types.UpstreamProxy, error) {
ret := _m.Called(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search)
if len(ret) == 0 {
panic("no return value specified for GetAll")
}
var r0 *[]types.UpstreamProxy
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, []string, string, string, int, int, string) (*[]types.UpstreamProxy, error)); ok {
return rf(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, []string, string, string, int, int, string) *[]types.UpstreamProxy); ok {
r0 = rf(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.UpstreamProxy)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, []string, string, string, int, int, string) error); ok {
r1 = rf(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByParentID provides a mock function with given fields: ctx, parentID
func (_m *UpstreamProxyConfigRepository) GetByParentID(ctx context.Context, parentID string) (*[]types.UpstreamProxy, error) {
ret := _m.Called(ctx, parentID)
if len(ret) == 0 {
panic("no return value specified for GetByParentID")
}
var r0 *[]types.UpstreamProxy
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (*[]types.UpstreamProxy, error)); ok {
return rf(ctx, parentID)
}
if rf, ok := ret.Get(0).(func(context.Context, string) *[]types.UpstreamProxy); ok {
r0 = rf(ctx, parentID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.UpstreamProxy)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, parentID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByRegistryIdentifier provides a mock function with given fields: ctx, parentID, repoKey
func (_m *UpstreamProxyConfigRepository) GetByRegistryIdentifier(ctx context.Context, parentID int64, repoKey string) (*types.UpstreamProxy, error) {
ret := _m.Called(ctx, parentID, repoKey)
if len(ret) == 0 {
panic("no return value specified for GetByRegistryIdentifier")
}
var r0 *types.UpstreamProxy
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) (*types.UpstreamProxy, error)); ok {
return rf(ctx, parentID, repoKey)
}
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.UpstreamProxy); ok {
r0 = rf(ctx, parentID, repoKey)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.UpstreamProxy)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, parentID, repoKey)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Update provides a mock function with given fields: ctx, upstreamproxyRecord
func (_m *UpstreamProxyConfigRepository) Update(ctx context.Context, upstreamproxyRecord *types.UpstreamProxyConfig) error {
ret := _m.Called(ctx, upstreamproxyRecord)
if len(ret) == 0 {
panic("no return value specified for Update")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.UpstreamProxyConfig) error); ok {
r0 = rf(ctx, upstreamproxyRecord)
} else {
r0 = ret.Error(0)
}
return r0
}
// NewUpstreamProxyConfigRepository creates a new instance of UpstreamProxyConfigRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewUpstreamProxyConfigRepository(t interface {
mock.TestingT
Cleanup(func())
}) *UpstreamProxyConfigRepository {
mock := &UpstreamProxyConfigRepository{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,176 @@
package mocks
import (
"context"
"github.com/harness/gitness/registry/types"
"github.com/stretchr/testify/mock"
)
// UpstreamProxyStore is an autogenerated mock type for the UpstreamProxyConfigRepository type
type UpstreamProxyStore struct {
mock.Mock
}
// Get provides a mock function with given fields: ctx, id
func (m *UpstreamProxyStore) Get(ctx context.Context, id int64) (*types.UpstreamProxy, error) {
ret := m.Called(ctx, id)
var r0 *types.UpstreamProxy
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.UpstreamProxy); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.UpstreamProxy)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByRegistryIdentifier provides a mock function with given fields: ctx, parentID, repoKey
func (m *UpstreamProxyStore) GetByRegistryIdentifier(ctx context.Context, parentID int64, repoKey string) (*types.UpstreamProxy, error) {
ret := m.Called(ctx, parentID, repoKey)
var r0 *types.UpstreamProxy
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.UpstreamProxy); ok {
r0 = rf(ctx, parentID, repoKey)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.UpstreamProxy)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, parentID, repoKey)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetByParentID provides a mock function with given fields: ctx, parentID
func (m *UpstreamProxyStore) GetByParentID(ctx context.Context, parentID string) (*[]types.UpstreamProxy, error) {
ret := m.Called(ctx, parentID)
var r0 *[]types.UpstreamProxy
if rf, ok := ret.Get(0).(func(context.Context, string) *[]types.UpstreamProxy); ok {
r0 = rf(ctx, parentID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.UpstreamProxy)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, parentID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Create provides a mock function with given fields: ctx, upstreamproxyRecord
func (m *UpstreamProxyStore) Create(ctx context.Context, upstreamproxyRecord *types.UpstreamProxyConfig) (int64, error) {
ret := m.Called(ctx, upstreamproxyRecord)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context, *types.UpstreamProxyConfig) int64); ok {
r0 = rf(ctx, upstreamproxyRecord)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *types.UpstreamProxyConfig) error); ok {
r1 = rf(ctx, upstreamproxyRecord)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Delete provides a mock function with given fields: ctx, parentID, repoKey
func (m *UpstreamProxyStore) Delete(ctx context.Context, parentID int64, repoKey string) error {
ret := m.Called(ctx, parentID, repoKey)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, int64, string) error); ok {
r0 = rf(ctx, parentID, repoKey)
} else {
r0 = ret.Error(0)
}
return r0
}
// Update provides a mock function with given fields: ctx, upstreamproxyRecord
func (m *UpstreamProxyStore) Update(ctx context.Context, upstreamproxyRecord *types.UpstreamProxyConfig) error {
ret := m.Called(ctx, upstreamproxyRecord)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *types.UpstreamProxyConfig) error); ok {
r0 = rf(ctx, upstreamproxyRecord)
} else {
r0 = ret.Error(0)
}
return r0
}
// GetAll provides a mock function with given fields: ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search
func (m *UpstreamProxyStore) GetAll(ctx context.Context, parentID int64, packageTypes []string, sortByField string, sortByOrder string, limit int, offset int, search string) (*[]types.UpstreamProxy, error) {
ret := m.Called(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search)
var r0 *[]types.UpstreamProxy
if rf, ok := ret.Get(0).(func(context.Context, int64, []string, string, string, int, int, string) *[]types.UpstreamProxy); ok {
r0 = rf(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*[]types.UpstreamProxy)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, []string, string, string, int, int, string) error); ok {
r1 = rf(ctx, parentID, packageTypes, sortByField, sortByOrder, limit, offset, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountAll provides a mock function with given fields: ctx, parentID, packageTypes, search
func (m *UpstreamProxyStore) CountAll(ctx context.Context, parentID string, packageTypes []string, search string) (int64, error) {
ret := m.Called(ctx, parentID, packageTypes, search)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context, string, []string, string) int64); ok {
r0 = rf(ctx, parentID, packageTypes, search)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string, []string, string) error); ok {
r1 = rf(ctx, parentID, packageTypes, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -0,0 +1,337 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package mocks
import (
context "context"
mock "github.com/stretchr/testify/mock"
)
// Provider is an autogenerated mock type for the Provider type
type Provider struct {
mock.Mock
}
// GenerateContainerGITCloneURL provides a mock function with given fields: ctx, repoPath
func (_m *Provider) GenerateContainerGITCloneURL(ctx context.Context, repoPath string) string {
ret := _m.Called(ctx, repoPath)
if len(ret) == 0 {
panic("no return value specified for GenerateContainerGITCloneURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string) string); ok {
r0 = rf(ctx, repoPath)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateGITCloneSSHURL provides a mock function with given fields: ctx, repoPath
func (_m *Provider) GenerateGITCloneSSHURL(ctx context.Context, repoPath string) string {
ret := _m.Called(ctx, repoPath)
if len(ret) == 0 {
panic("no return value specified for GenerateGITCloneSSHURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string) string); ok {
r0 = rf(ctx, repoPath)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateGITCloneURL provides a mock function with given fields: ctx, repoPath
func (_m *Provider) GenerateGITCloneURL(ctx context.Context, repoPath string) string {
ret := _m.Called(ctx, repoPath)
if len(ret) == 0 {
panic("no return value specified for GenerateGITCloneURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string) string); ok {
r0 = rf(ctx, repoPath)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateUIBuildURL provides a mock function with given fields: ctx, repoPath, pipelineIdentifier, seqNumber
func (_m *Provider) GenerateUIBuildURL(ctx context.Context, repoPath string, pipelineIdentifier string, seqNumber int64) string {
ret := _m.Called(ctx, repoPath, pipelineIdentifier, seqNumber)
if len(ret) == 0 {
panic("no return value specified for GenerateUIBuildURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string, string, int64) string); ok {
r0 = rf(ctx, repoPath, pipelineIdentifier, seqNumber)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateUICompareURL provides a mock function with given fields: ctx, repoPath, ref1, ref2
func (_m *Provider) GenerateUICompareURL(ctx context.Context, repoPath string, ref1 string, ref2 string) string {
ret := _m.Called(ctx, repoPath, ref1, ref2)
if len(ret) == 0 {
panic("no return value specified for GenerateUICompareURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string, string, string) string); ok {
r0 = rf(ctx, repoPath, ref1, ref2)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateUIPRURL provides a mock function with given fields: ctx, repoPath, prID
func (_m *Provider) GenerateUIPRURL(ctx context.Context, repoPath string, prID int64) string {
ret := _m.Called(ctx, repoPath, prID)
if len(ret) == 0 {
panic("no return value specified for GenerateUIPRURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string, int64) string); ok {
r0 = rf(ctx, repoPath, prID)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateUIRefURL provides a mock function with given fields: ctx, repoPath, ref
func (_m *Provider) GenerateUIRefURL(ctx context.Context, repoPath string, ref string) string {
ret := _m.Called(ctx, repoPath, ref)
if len(ret) == 0 {
panic("no return value specified for GenerateUIRefURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string, string) string); ok {
r0 = rf(ctx, repoPath, ref)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateUIRegistryURL provides a mock function with given fields: ctx, parentSpacePath, registryName
func (_m *Provider) GenerateUIRegistryURL(ctx context.Context, parentSpacePath string, registryName string) string {
ret := _m.Called(ctx, parentSpacePath, registryName)
if len(ret) == 0 {
panic("no return value specified for GenerateUIRegistryURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string, string) string); ok {
r0 = rf(ctx, parentSpacePath, registryName)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GenerateUIRepoURL provides a mock function with given fields: ctx, repoPath
func (_m *Provider) GenerateUIRepoURL(ctx context.Context, repoPath string) string {
ret := _m.Called(ctx, repoPath)
if len(ret) == 0 {
panic("no return value specified for GenerateUIRepoURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string) string); ok {
r0 = rf(ctx, repoPath)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GetAPIHostname provides a mock function with given fields: ctx
func (_m *Provider) GetAPIHostname(ctx context.Context) string {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetAPIHostname")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context) string); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GetAPIProto provides a mock function with given fields: ctx
func (_m *Provider) GetAPIProto(ctx context.Context) string {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetAPIProto")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context) string); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GetGITHostname provides a mock function with given fields: ctx
func (_m *Provider) GetGITHostname(ctx context.Context) string {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetGITHostname")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context) string); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GetInternalAPIURL provides a mock function with given fields: ctx
func (_m *Provider) GetInternalAPIURL(ctx context.Context) string {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetInternalAPIURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context) string); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GetUIBaseURL provides a mock function with given fields: ctx, params
func (_m *Provider) GetUIBaseURL(ctx context.Context, params ...string) string {
_va := make([]interface{}, len(params))
for _i := range params {
_va[_i] = params[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for GetUIBaseURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, ...string) string); ok {
r0 = rf(ctx, params...)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// PackageURL provides a mock function with given fields: ctx, regRef, pkgType, params
func (_m *Provider) PackageURL(ctx context.Context, regRef string, pkgType string, params ...string) string {
_va := make([]interface{}, len(params))
for _i := range params {
_va[_i] = params[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, regRef, pkgType)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for PackageURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, string, string, ...string) string); ok {
r0 = rf(ctx, regRef, pkgType, params...)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// RegistryURL provides a mock function with given fields: ctx, params
func (_m *Provider) RegistryURL(ctx context.Context, params ...string) string {
_va := make([]interface{}, len(params))
for _i := range params {
_va[_i] = params[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RegistryURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(context.Context, ...string) string); ok {
r0 = rf(ctx, params...)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// NewProvider creates a new instance of Provider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewProvider(t interface {
mock.TestingT
Cleanup(func())
}) *Provider {
mock := &Provider{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,39 @@
// Code generated by testify. DO NOT EDIT.
package mocks
import (
"context"
gitnesswebhook "github.com/harness/gitness/app/services/webhook"
"github.com/stretchr/testify/mock"
)
// WebhookService is a mock of WebhookService interface.
type WebhookService struct {
mock.Mock
}
// ReTriggerWebhookExecution provides a mock function
func (m *WebhookService) ReTriggerWebhookExecution(ctx context.Context, webhookExecutionID int64) (*gitnesswebhook.TriggerResult, error) {
ret := m.Called(ctx, webhookExecutionID)
var r0 *gitnesswebhook.TriggerResult
if rf, ok := ret.Get(0).(func(context.Context, int64) *gitnesswebhook.TriggerResult); ok {
r0 = rf(ctx, webhookExecutionID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*gitnesswebhook.TriggerResult)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, webhookExecutionID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -0,0 +1,112 @@
// Code generated by testify. DO NOT EDIT.
package mocks
import (
"context"
"github.com/harness/gitness/types"
"github.com/stretchr/testify/mock"
)
// WebhooksExecutionRepository is a mock of store.WebhooksExecutionRepository interface.
type WebhooksExecutionRepository struct {
mock.Mock
}
// Find provides a mock function
func (m *WebhooksExecutionRepository) Find(ctx context.Context, id int64) (*types.WebhookExecutionCore, error) {
ret := m.Called(ctx, id)
var r0 *types.WebhookExecutionCore
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.WebhookExecutionCore); ok {
r0 = rf(ctx, id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.WebhookExecutionCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Create provides a mock function
func (m *WebhooksExecutionRepository) Create(ctx context.Context, hook *types.WebhookExecutionCore) error {
ret := m.Called(ctx, hook)
return ret.Error(0)
}
// ListForWebhook provides a mock function
func (m *WebhooksExecutionRepository) ListForWebhook(ctx context.Context, webhookID int64, limit int, page int, size int) ([]*types.WebhookExecutionCore, error) {
ret := m.Called(ctx, webhookID, limit, page, size)
var r0 []*types.WebhookExecutionCore
if rf, ok := ret.Get(0).(func(context.Context, int64, int, int, int) []*types.WebhookExecutionCore); ok {
r0 = rf(ctx, webhookID, limit, page, size)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*types.WebhookExecutionCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, int, int, int) error); ok {
r1 = rf(ctx, webhookID, limit, page, size)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountForWebhook provides a mock function
func (m *WebhooksExecutionRepository) CountForWebhook(ctx context.Context, webhookID int64) (int64, error) {
ret := m.Called(ctx, webhookID)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context, int64) int64); ok {
r0 = rf(ctx, webhookID)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, webhookID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListForTrigger provides a mock function
func (m *WebhooksExecutionRepository) ListForTrigger(ctx context.Context, triggerID string) ([]*types.WebhookExecutionCore, error) {
ret := m.Called(ctx, triggerID)
var r0 []*types.WebhookExecutionCore
if rf, ok := ret.Get(0).(func(context.Context, string) []*types.WebhookExecutionCore); ok {
r0 = rf(ctx, triggerID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*types.WebhookExecutionCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, triggerID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -0,0 +1,170 @@
// Code generated by testify. DO NOT EDIT.
package mocks
import (
"context"
"github.com/harness/gitness/types"
"github.com/stretchr/testify/mock"
)
// WebhooksRepository is a mock of store.WebhooksRepository interface.
type WebhooksRepository struct {
mock.Mock
}
// Create provides a mock function
func (m *WebhooksRepository) Create(ctx context.Context, webhook *types.WebhookCore) error {
ret := m.Called(ctx, webhook)
return ret.Error(0)
}
// GetByRegistryAndIdentifier provides a mock function
func (m *WebhooksRepository) GetByRegistryAndIdentifier(ctx context.Context, registryID int64, webhookIdentifier string) (*types.WebhookCore, error) {
ret := m.Called(ctx, registryID, webhookIdentifier)
var r0 *types.WebhookCore
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *types.WebhookCore); ok {
r0 = rf(ctx, registryID, webhookIdentifier)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.WebhookCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, registryID, webhookIdentifier)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Find provides a mock function
func (m *WebhooksRepository) Find(ctx context.Context, webhookID int64) (*types.WebhookCore, error) {
ret := m.Called(ctx, webhookID)
var r0 *types.WebhookCore
if rf, ok := ret.Get(0).(func(context.Context, int64) *types.WebhookCore); ok {
r0 = rf(ctx, webhookID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.WebhookCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
r1 = rf(ctx, webhookID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListByRegistry provides a mock function
func (m *WebhooksRepository) ListByRegistry(ctx context.Context, sortByField string, sortByOrder string, limit int, offset int, search string, registryID int64) ([]*types.WebhookCore, error) {
ret := m.Called(ctx, sortByField, sortByOrder, limit, offset, search, registryID)
var r0 []*types.WebhookCore
if rf, ok := ret.Get(0).(func(context.Context, string, string, int, int, string, int64) []*types.WebhookCore); ok {
r0 = rf(ctx, sortByField, sortByOrder, limit, offset, search, registryID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*types.WebhookCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string, string, int, int, string, int64) error); ok {
r1 = rf(ctx, sortByField, sortByOrder, limit, offset, search, registryID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllByRegistry provides a mock function
func (m *WebhooksRepository) ListAllByRegistry(ctx context.Context, parents []types.WebhookParentInfo) ([]*types.WebhookCore, error) {
ret := m.Called(ctx, parents)
var r0 []*types.WebhookCore
if rf, ok := ret.Get(0).(func(context.Context, []types.WebhookParentInfo) []*types.WebhookCore); ok {
r0 = rf(ctx, parents)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*types.WebhookCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, []types.WebhookParentInfo) error); ok {
r1 = rf(ctx, parents)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountAllByRegistry provides a mock function
func (m *WebhooksRepository) CountAllByRegistry(ctx context.Context, registryID int64, search string) (int64, error) {
ret := m.Called(ctx, registryID, search)
var r0 int64
if rf, ok := ret.Get(0).(func(context.Context, int64, string) int64); ok {
r0 = rf(ctx, registryID, search)
} else {
r0 = ret.Get(0).(int64)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, registryID, search)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Update provides a mock function
func (m *WebhooksRepository) Update(ctx context.Context, webhook *types.WebhookCore) error {
ret := m.Called(ctx, webhook)
return ret.Error(0)
}
// DeleteByRegistryAndIdentifier provides a mock function
func (m *WebhooksRepository) DeleteByRegistryAndIdentifier(ctx context.Context, registryID int64, webhookIdentifier string) error {
ret := m.Called(ctx, registryID, webhookIdentifier)
return ret.Error(0)
}
// UpdateOptLock provides a mock function
func (m *WebhooksRepository) UpdateOptLock(ctx context.Context, hook *types.WebhookCore, fn func(hook *types.WebhookCore) error) (*types.WebhookCore, error) {
ret := m.Called(ctx, hook, fn)
var r0 *types.WebhookCore
if rf, ok := ret.Get(0).(func(context.Context, *types.WebhookCore, func(*types.WebhookCore) error) *types.WebhookCore); ok {
r0 = rf(ctx, hook, fn)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.WebhookCore)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *types.WebhookCore, func(*types.WebhookCore) error) error); ok {
r1 = rf(ctx, hook, fn)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -1,4 +1,4 @@
// Copyright 2023 Harness, Inc.
// 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.
@ -12,49 +12,59 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata
package interfaces
import (
"context"
gitnesswebhook "github.com/harness/gitness/app/services/webhook"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
registrytypes "github.com/harness/gitness/registry/types"
"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)
}
// RegistryMetadataHelper provides helper methods for registry metadata operations.
type RegistryMetadataHelper interface {
// GetRegistryRequestBaseInfo retrieves base info for registry request.
GetRegistryRequestBaseInfo(
ctx context.Context,
parentPath string,
identifier string,
) (*registrytypes.RegistryRequestBaseInfo, error)
// GetPermissionChecks returns permission checks for registry operations.
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) (int64, error)
MapToAPIWebhookTriggers(triggers []enum.WebhookTrigger) []api.Trigger
MapToInternalWebhookTriggers(
triggers []api.Trigger,
) []enum.WebhookTrigger
// MapToWebhookCore maps webhook request to core webhook type.
MapToWebhookCore(
ctx context.Context,
webhookRequest api.WebhookRequest,
regInfo *RegistryRequestBaseInfo,
regInfo *registrytypes.RegistryRequestBaseInfo,
) (*types.WebhookCore, error)
// MapToWebhookResponseEntity maps webhook core to response entity.
MapToWebhookResponseEntity(
ctx context.Context,
createdWebhook *types.WebhookCore,
webhook *types.WebhookCore,
) (*api.Webhook, error)
}
type WebhookService interface {
ReTriggerWebhookExecution(ctx context.Context, webhookExecutionID int64) (*gitnesswebhook.TriggerResult, error)
// MapToInternalWebhookTriggers maps webhook triggers to internal type.
MapToInternalWebhookTriggers(
triggers []api.Trigger,
) []enum.WebhookTrigger
// MapToAPIWebhookTriggers maps webhook triggers to API type.
MapToAPIWebhookTriggers(
triggers []enum.WebhookTrigger,
) []api.Trigger
// GetSecretSpaceID retrieves secret space ID from secret space path.
GetSecretSpaceID(
ctx context.Context,
secretSpacePath *string,
) (int64, error)
}

View File

@ -0,0 +1,30 @@
// 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 interfaces
import (
"context"
"github.com/harness/gitness/types"
)
// SpaceFinder defines the interface for finding spaces.
type SpaceFinder interface {
// FindByID finds the space by id.
FindByID(ctx context.Context, id int64) (*types.SpaceCore, error)
// FindByRef finds the space using the spaceRef as either the id or the space path.
FindByRef(ctx context.Context, spaceRef string) (*types.SpaceCore, error)
}

View File

@ -21,11 +21,11 @@ import (
"github.com/harness/gitness/app/api/middleware/encode"
"github.com/harness/gitness/app/auth/authn"
"github.com/harness/gitness/app/auth/authz"
"github.com/harness/gitness/app/services/refcache"
corestore "github.com/harness/gitness/app/store"
urlprovider "github.com/harness/gitness/app/url"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/interfaces"
"github.com/harness/gitness/registry/app/api/middleware"
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
storagedriver "github.com/harness/gitness/registry/app/driver"
@ -64,7 +64,7 @@ func NewAPIHandler(
imageDao store.ImageRepository,
driver storagedriver.StorageDriver,
baseURL string,
spaceFinder refcache.SpaceFinder,
spaceFinder interfaces.SpaceFinder,
tx dbtx.Transactor,
authenticator authn.Authenticator,
urlProvider urlprovider.Provider,

View File

@ -0,0 +1,26 @@
// 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 webhook
import (
"context"
gitnesswebhook "github.com/harness/gitness/app/services/webhook"
)
// Service interface for webhook operations.
type ServiceInterface interface {
ReTriggerWebhookExecution(ctx context.Context, webhookExecutionID int64) (*gitnesswebhook.TriggerResult, error)
}

View File

@ -35,6 +35,9 @@ const (
eventsReaderGroupName = "gitness:webhook"
)
// Verify Service implements ServiceInterface.
var _ ServiceInterface = (*Service)(nil)
// Service is responsible for processing webhook events.
type Service struct {
WebhookExecutor *gitnesswebhook.WebhookExecutor

37
registry/types/request.go Normal file
View File

@ -0,0 +1,37 @@
// 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 types
import (
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
)
// RegistryRequestBaseInfo represents base information about a registry request.
type RegistryRequestBaseInfo struct {
RootIdentifier string
RootIdentifierID int64
RegistryRef string
RegistryIdentifier string
RegistryID int64
ParentRef string
ParentID int64
RegistryType api.RegistryType
PackageType api.PackageType
}
// ArtifactFilesRequestInfo represents base information about an artifact files request.
type ArtifactFilesRequestInfo struct {
RegistryRequestBaseInfo
}

View File

@ -0,0 +1,30 @@
// 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 utils
import (
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
)
// Helper functions for creating pointers.
func StringPtr(s string) *string { return &s }
func Int64Ptr(i int64) *int64 { return &i }
func IntPtr(i int) *int { return &i }
func BoolPtr(b bool) *bool { return &b }
func Int32Ptr(i int32) *int32 { return &i }
func WebhookExecResultPtr(r api.WebhookExecResult) *api.WebhookExecResult { return &r }
func WebhookTriggerPtr(t api.Trigger) *api.Trigger { return &t }
func PageSizePtr(i int32) *api.PageSize { size := api.PageSize(i); return &size }
func PageNumberPtr(i int32) *api.PageNumber { num := api.PageNumber(i); return &num }