package api import ( "context" "encoding/json" "errors" "fmt" "net/url" "strings" "testing" "time" "buf.build/go/protovalidate" "github.com/Azure/go-amqp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "go.opentelemetry.io/otel" auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/gen/go/audit/v1" internalAuditApi "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/internal/audit/api" pkgAuditCommon "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/pkg/audit/common" pkgMessagingApi "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/pkg/messaging/api" pkgMessagingCommon "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/pkg/messaging/common" pkgMessagingTest "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/pkg/messaging/test" ) func TestLegacyAuditApi(t *testing.T) { // Specify test timeout ctx, cancelFn := context.WithTimeout(context.Background(), 120*time.Second) defer cancelFn() // Start solace docker container solaceContainer, err := pkgMessagingTest.NewSolaceContainer(context.Background()) assert.NoError(t, err) defer solaceContainer.Stop() // Instantiate the messaging api amqpApi, err := pkgMessagingApi.NewAmqpApi(pkgMessagingCommon.AmqpConnectionPoolConfig{ Parameters: pkgMessagingCommon.AmqpConnectionConfig{BrokerUrl: solaceContainer.AmqpConnectionString}, PoolSize: 1, }) assert.NoError(t, err) // Validator validator, err := protovalidate.New() assert.NoError(t, err) topicSubscriptionTopicPattern := "stackit-platform/t/swz/audit-log/>" // Check that event-type data-access is rejected as it is currently // not supported by downstream services t.Run("reject data access event", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "org-reject-data-access-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/organization-rejected" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewOrganizationAuditEvent(nil) event.LogName = strings.Replace(event.LogName, string(pkgAuditCommon.EventTypeAdminActivity), string(pkgAuditCommon.EventTypeDataAccess), 1) // Log the event to solace assert.ErrorIs(t, auditApi.Log( ctx, event, auditV1.Visibility_VISIBILITY_PUBLIC, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), ), pkgAuditCommon.ErrUnsupportedEventTypeDataAccess) }) // Check logging of organization events t.Run("Log public organization event", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "org-event-public-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/organization-created" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewOrganizationAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PUBLIC assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), )) message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) validateSentMessage(t, topicName, message, event) }) t.Run("Log private organization event", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "org-event-private-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/organization-created" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewOrganizationAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PRIVATE assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), )) message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) validateSentMessage(t, topicName, message, event) }) // Check logging of folder events t.Run("Log public folder event", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "folder-event-public-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/folder-created" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewFolderAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PUBLIC assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), )) message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) validateSentMessage(t, topicName, message, event) }) t.Run("Log private folder event", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "folder-event-private-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/folder-created" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewFolderAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PRIVATE assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), )) message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) validateSentMessage(t, topicName, message, event) }) // Check logging of project events t.Run("Log public project event", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "project-event-public-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/project-created" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewProjectAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PUBLIC assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), )) message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) validateSentMessage(t, topicName, message, event) }) t.Run("Log private project event", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "project-event-private-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/project-created" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewProjectAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PRIVATE assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), )) message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) validateSentMessage(t, topicName, message, event) }) // Check logging of system events with identifier t.Run("Log private project system event", func(t *testing.T) { defer solaceContainer.StopOnError() queueName := "project-system-event-private" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/project-system-changed" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event := internalAuditApi.NewProjectSystemAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PRIVATE assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.RoutableSystemIdentifier, )) // Receive the event from solace message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) // Check topic name assert.Equal(t, topicName, *message.Properties.To) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:traceparent"]) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:tracestate"]) // Check deserialized message var auditEvent internalAuditApi.LegacyAuditEvent assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) assert.Equal(t, event.ProtoPayload.ResourceName, *auditEvent.ResourceName) assert.Equal(t, event.ProtoPayload.OperationName, auditEvent.EventName) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp) assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id) assert.Equal(t, "SYSTEM_EVENT", auditEvent.EventType) assert.Equal(t, "INFO", auditEvent.Severity) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint) assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress) assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent) }) // Check logging of system events t.Run("Log private system event", func(t *testing.T) { defer solaceContainer.StopOnError() queueName := "system-event-private" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/system-changed" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event := internalAuditApi.NewSystemAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PRIVATE assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.RoutableSystemIdentifier, )) // Receive the event from solace message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) // Check topic name assert.Equal(t, topicName, *message.Properties.To) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:traceparent"]) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:tracestate"]) // Check deserialized message var auditEvent internalAuditApi.LegacyAuditEvent assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) assert.Equal(t, event.ProtoPayload.OperationName, auditEvent.EventName) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp) assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id) assert.Equal(t, "SYSTEM_EVENT", auditEvent.EventType) assert.Equal(t, "INFO", auditEvent.Severity) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint) assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress) assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent) }) t.Run("Log event with details", func(t *testing.T) { defer solaceContainer.StopOnError() // Create the queue and topic subscription in solace queueName := "org-event-with-details-legacy" assert.NoError(t, solaceContainer.QueueCreate(ctx, queueName)) assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, topicSubscriptionTopicPattern)) topicName := "topic://stackit-platform/t/swz/audit-log/eu01/v1/resource-manager/organization-created" assert.NoError(t, solaceContainer.ValidateTopicName(topicSubscriptionTopicPattern, topicName)) // Instantiate audit api auditApi, err := NewLegacyAuditApi( amqpApi, StaticTopicNameConfig{TopicName: topicName}, validator, ) assert.NoError(t, err) // Instantiate test data event, objectIdentifier := internalAuditApi.NewOrganizationAuditEvent(nil) escapedQuery := url.QueryEscape("param=value") event.ProtoPayload.RequestMetadata.RequestAttributes.Query = &escapedQuery // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PUBLIC assert.NoError(t, auditApi.Log( ctx, event, visibility, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier), )) message, err := solaceContainer.NextMessageFromQueue(ctx, queueName, true) assert.NoError(t, err) validateSentMessageWithDetails(t, topicName, message, event) }) } func validateSentMessage( t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditLogEntry, ) { // Check message properties assert.Equal(t, topicName, *message.Properties.To) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:traceparent"]) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:tracestate"]) // Check deserialized message var auditEvent internalAuditApi.LegacyAuditEvent assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) var severity string switch event.Severity { case auditV1.LogSeverity_LOG_SEVERITY_DEFAULT: fallthrough case auditV1.LogSeverity_LOG_SEVERITY_DEBUG: fallthrough case auditV1.LogSeverity_LOG_SEVERITY_INFO: fallthrough case auditV1.LogSeverity_LOG_SEVERITY_NOTICE: fallthrough case auditV1.LogSeverity_LOG_SEVERITY_WARNING: severity = "INFO" case auditV1.LogSeverity_LOG_SEVERITY_ERROR: fallthrough case auditV1.LogSeverity_LOG_SEVERITY_CRITICAL: fallthrough case auditV1.LogSeverity_LOG_SEVERITY_ALERT: fallthrough case auditV1.LogSeverity_LOG_SEVERITY_EMERGENCY: severity = "ERROR" default: assert.Fail(t, "unknown log severity") } assert.Equal(t, event.ProtoPayload.OperationName, auditEvent.EventName) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp) assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id) assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType) assert.Equal(t, severity, auditEvent.Severity) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint) assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress) assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent) } func validateSentMessageWithDetails( t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditLogEntry, ) { // Check topic name assert.Equal(t, topicName, *message.Properties.To) assert.Equal(t, pkgAuditCommon.ContentTypeCloudEventsJson, message.ApplicationProperties["cloudEvents:datacontenttype"]) assert.Equal(t, DataTypeLegacyAuditEventV1, message.ApplicationProperties["cloudEvents:type"]) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:traceparent"]) assert.Equal(t, "", message.ApplicationProperties["cloudEvents:tracestate"]) // Check deserialized message var auditEvent internalAuditApi.LegacyAuditEvent assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) assert.Equal(t, event.ProtoPayload.OperationName, auditEvent.EventName) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp) assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id) assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType) assert.Equal(t, "INFO", auditEvent.Severity) assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint) var parameters map[string]interface{} = nil if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" && event.ProtoPayload.RequestMetadata.RequestAttributes.Query != nil && *event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" { parameters = map[string]interface{}{} unescapedQuery, err := url.QueryUnescape(*event.ProtoPayload.RequestMetadata.RequestAttributes.Query) assert.NoError(t, err) parsedUrl, err := url.Parse(fmt.Sprintf("%s?%s", event.ProtoPayload.RequestMetadata.RequestAttributes.Path, unescapedQuery)) assert.NoError(t, err) for k, v := range parsedUrl.Query() { parameters[k] = v } } assert.Equal(t, event.ProtoPayload.Request.AsMap(), *auditEvent.Request.Body) assert.Equal(t, parameters, *auditEvent.Request.Parameters) for key, value := range event.ProtoPayload.RequestMetadata.RequestAttributes.Headers { assert.Equal(t, value, (*auditEvent.Request.Headers)[key]) } assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress) assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent) assert.Equal(t, event.ProtoPayload.Request.AsMap(), *auditEvent.Details) assert.Equal(t, event.ProtoPayload.Response.AsMap(), *auditEvent.Result) assert.True(t, auditEvent.Context.OrganizationId != nil || auditEvent.Context.FolderId != nil || auditEvent.Context.ProjectId != nil) for idx, principal := range event.ProtoPayload.AuthenticationInfo.ServiceAccountDelegationInfo { switch principalValue := principal.Authority.(type) { case *auditV1.ServiceAccountDelegationInfo_IdpPrincipal_: assert.Equal(t, principalValue.IdpPrincipal.PrincipalId, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id) assert.Equal(t, principalValue.IdpPrincipal.PrincipalEmail, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Email) case *auditV1.ServiceAccountDelegationInfo_SystemPrincipal_: assert.Equal(t, "system", auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id) } } } func TestLegacyAuditApi_NewLegacyAuditApi(t *testing.T) { t.Run("messaging api nil", func(t *testing.T) { auditApi, err := NewLegacyAuditApi(nil, StaticTopicNameConfig{}, nil) assert.Nil(t, auditApi) assert.EqualError(t, err, "messaging api nil") }) t.Run("topic name is blank", func(t *testing.T) { // Start solace docker container solaceContainer, err := pkgMessagingTest.NewSolaceContainer(context.Background()) assert.NoError(t, err) defer solaceContainer.Stop() // Instantiate the messaging api amqpApi, err := pkgMessagingApi.NewAmqpApi(pkgMessagingCommon.AmqpConnectionPoolConfig{ Parameters: pkgMessagingCommon.AmqpConnectionConfig{BrokerUrl: solaceContainer.AmqpConnectionString}, PoolSize: 1, }) assert.NoError(t, err) // Validator validator, err := protovalidate.New() assert.NoError(t, err) auditApi, err := NewLegacyAuditApi(amqpApi, StaticTopicNameConfig{ TopicName: "", }, validator) assert.Nil(t, auditApi) assert.EqualError(t, err, "topic name is required") }) } func TestLegacyAuditApi_ValidateAndSerialize_ValidationFailed(t *testing.T) { expectedError := errors.New("expected error") validator := &ProtobufValidatorMock{} validator.On("Validate", mock.Anything).Return(expectedError) var protobufValidator pkgAuditCommon.ProtobufValidator = validator auditApi := LegacyAuditApi{ tracer: otel.Tracer("test"), validator: protobufValidator, } event := internalAuditApi.NewSystemAuditEvent(nil) _, err := auditApi.ValidateAndSerialize(context.Background(), event, auditV1.Visibility_VISIBILITY_PUBLIC, pkgAuditCommon.RoutableSystemIdentifier) assert.ErrorIs(t, err, expectedError) } func TestLegacyAuditApi_Log_ValidationFailed(t *testing.T) { expectedError := errors.New("expected error") validator := &ProtobufValidatorMock{} validator.On("Validate", mock.Anything).Return(expectedError) var protobufValidator pkgAuditCommon.ProtobufValidator = validator auditApi := LegacyAuditApi{ tracer: otel.Tracer("test"), validator: protobufValidator, } event := internalAuditApi.NewSystemAuditEvent(nil) err := auditApi.Log(context.Background(), event, auditV1.Visibility_VISIBILITY_PUBLIC, pkgAuditCommon.RoutableSystemIdentifier) assert.ErrorIs(t, err, expectedError) } func TestLegacyAuditApi_Log_NilEvent(t *testing.T) { auditApi := LegacyAuditApi{tracer: otel.Tracer("test")} err := auditApi.Log(context.Background(), nil, auditV1.Visibility_VISIBILITY_PUBLIC, pkgAuditCommon.RoutableSystemIdentifier) assert.ErrorIs(t, err, pkgAuditCommon.ErrEventNil) } func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormatInvalidObjectIdentifierType(t *testing.T) { customization := func(event *auditV1.AuditLogEntry, objectIdentifier *auditV1.ObjectIdentifier) { objectIdentifier.Type = "invalid" } event, objectIdentifier := internalAuditApi.NewProjectAuditEvent(&customization) validator := &ProtobufValidatorMock{} validator.On("Validate", mock.Anything).Return(nil) var protobufValidator pkgAuditCommon.ProtobufValidator = validator auditApi := LegacyAuditApi{ tracer: otel.Tracer("test"), validator: protobufValidator, } _, err := auditApi.ValidateAndSerialize(context.Background(), event, auditV1.Visibility_VISIBILITY_PUBLIC, pkgAuditCommon.NewRoutableIdentifier(objectIdentifier)) assert.ErrorIs(t, err, pkgAuditCommon.ErrUnsupportedRoutableType) }