audit-go/audit/api/api_common_test.go
2024-07-29 14:05:37 +02:00

242 lines
8.1 KiB
Go

package api
import (
"context"
"dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/audit/messaging"
auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1"
"errors"
"testing"
"github.com/bufbuild/protovalidate-go"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"google.golang.org/protobuf/proto"
)
type MessagingApiMock struct {
mock.Mock
}
func (m *MessagingApiMock) Send(
ctx context.Context,
topic string,
data []byte,
contentType string,
applicationProperties map[string]any,
) error {
args := m.Called(ctx, topic, data, contentType, applicationProperties)
return args.Error(0)
}
type ProtobufValidatorMock struct {
mock.Mock
}
func (m *ProtobufValidatorMock) Validate(msg proto.Message) error {
args := m.Called(msg)
return args.Error(0)
}
type TopicNameResolverMock struct {
mock.Mock
}
func (m *TopicNameResolverMock) Resolve(routingIdentifier *RoutingIdentifier) (string, error) {
args := m.Called(routingIdentifier)
return args.String(0), args.Error(1)
}
func NewValidator(t *testing.T) ProtobufValidator {
validator, err := protovalidate.New()
var protoValidator ProtobufValidator = validator
assert.NoError(t, err)
return protoValidator
}
func Test_ValidateAndSerializePartially_EventNil(t *testing.T) {
validator := NewValidator(t)
_, err := validateAndSerializePartially(
&validator, nil, auditV1.Visibility_VISIBILITY_PUBLIC, nil, nil)
assert.ErrorIs(t, err, ErrEventNil)
}
func Test_ValidateAndSerializePartially_AuditEventValidationFailed(t *testing.T) {
validator := NewValidator(t)
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
event.LogName = ""
_, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
assert.EqualError(t, err, "validation error:\n - log_name: value is required [required]")
}
func Test_ValidateAndSerializePartially_RoutableEventValidationFailed(t *testing.T) {
validator := NewValidator(t)
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
_, err := validateAndSerializePartially(&validator, event, 3, routingIdentifier, objectIdentifier)
assert.EqualError(t, err, "validation error:\n - visibility: value must be one of the defined enum values [enum.defined_only]")
}
func Test_ValidateAndSerializePartially_CheckVisibility(t *testing.T) {
validator := NewValidator(t)
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
t.Run("Visibility public - object identifier nil - routing identifier nil", func(t *testing.T) {
_, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, nil, nil)
assert.ErrorIs(t, err, ErrObjectIdentifierVisibilityMismatch)
})
t.Run("Visibility public - object identifier nil - routing identifier set", func(t *testing.T) {
_, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, nil)
assert.ErrorIs(t, err, ErrObjectIdentifierVisibilityMismatch)
})
t.Run("Visibility public - object identifier set - routing identifier nil", func(t *testing.T) {
_, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, nil, objectIdentifier)
assert.ErrorIs(t, err, ErrRoutableIdentifierMissing)
})
t.Run("Visibility public - object identifier set - routing identifier set", func(t *testing.T) {
routableEvent, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
assert.NoError(t, err)
assert.NotNil(t, routableEvent)
})
t.Run("Visibility private - object identifier nil - routing identifier nil", func(t *testing.T) {
routableEvent, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PRIVATE, nil, nil)
assert.NoError(t, err)
assert.NotNil(t, routableEvent)
})
t.Run("Visibility private - object identifier nil - routing identifier set", func(t *testing.T) {
routableEvent, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PRIVATE, routingIdentifier, nil)
assert.NoError(t, err)
assert.NotNil(t, routableEvent)
})
t.Run("Visibility private - object identifier set - routing identifier nil", func(t *testing.T) {
routableEvent, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PRIVATE, nil, objectIdentifier)
assert.NoError(t, err)
assert.NotNil(t, routableEvent)
})
t.Run("Visibility private - object identifier set - routing identifier set", func(t *testing.T) {
routableEvent, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PRIVATE, routingIdentifier, objectIdentifier)
assert.NoError(t, err)
assert.NotNil(t, routableEvent)
})
}
func Test_ValidateAndSerializePartially_IdentifierTypeMismatch(t *testing.T) {
validator := NewValidator(t)
event, routingIdentifier, objectIdentifier := NewFolderAuditEvent(nil)
routingIdentifier.Type = RoutingIdentifierTypeProject
_, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
assert.ErrorIs(t, err, ErrRoutableIdentifierTypeMismatch)
}
func Test_ValidateAndSerializePartially_IdentifierMismatch(t *testing.T) {
validator := NewValidator(t)
event, routingIdentifier, objectIdentifier := NewProjectAuditEvent(nil)
routingIdentifier.Identifier = uuid.New()
_, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
assert.ErrorIs(t, err, ErrRoutableIdentifierMismatch)
}
func Test_ValidateAndSerializePartially_SystemEvent(t *testing.T) {
validator := NewValidator(t)
event := NewSystemAuditEvent(nil)
routableEvent, err := validateAndSerializePartially(
&validator, event, auditV1.Visibility_VISIBILITY_PRIVATE, nil, nil)
assert.NoError(t, err)
switch reference := routableEvent.ResourceReference.(type) {
case *auditV1.RoutableAuditEvent_ObjectName:
assert.Equal(t, auditV1.ObjectName_OBJECT_NAME_SYSTEM, reference.ObjectName)
default:
assert.Fail(t, "unexpected resource reference")
}
}
func Test_Send_TopicNameResolverNil(t *testing.T) {
err := send(nil, nil, context.Background(), nil, nil)
assert.ErrorIs(t, err, ErrTopicNameResolverNil)
}
func Test_Send_TopicNameResolutionError(t *testing.T) {
expectedError := errors.New("expected error")
topicNameResolverMock := TopicNameResolverMock{}
topicNameResolverMock.On("Resolve", mock.Anything).Return("topic", expectedError)
var topicNameResolver TopicNameResolver = &topicNameResolverMock
var cloudEvent = CloudEvent{}
var messagingApi messaging.MessagingApi = &messaging.AmqpMessagingApi{}
err := send(&topicNameResolver, &messagingApi, context.Background(), nil, &cloudEvent)
assert.ErrorIs(t, err, expectedError)
}
func Test_Send_MessagingApiNil(t *testing.T) {
var topicNameResolver TopicNameResolver = &LegacyTopicNameResolver{topicName: "test"}
err := send(&topicNameResolver, nil, context.Background(), nil, nil)
assert.ErrorIs(t, err, ErrMessagingApiNil)
}
func Test_Send_SerializedPayloadNil(t *testing.T) {
var topicNameResolver TopicNameResolver = &LegacyTopicNameResolver{topicName: "test"}
var messagingApi messaging.MessagingApi = &messaging.AmqpMessagingApi{}
err := send(&topicNameResolver, &messagingApi, context.Background(), nil, nil)
assert.ErrorIs(t, err, ErrSerializedPayloadNil)
}
func Test_Send(t *testing.T) {
topicNameResolverMock := TopicNameResolverMock{}
topicNameResolverMock.On("Resolve", mock.Anything).Return("topic", nil)
var topicNameResolver TopicNameResolver = &topicNameResolverMock
messagingApiMock := MessagingApiMock{}
messagingApiMock.On("Send", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
var messagingApi messaging.MessagingApi = &messagingApiMock
var cloudEvent = CloudEvent{}
assert.NoError(t, send(&topicNameResolver, &messagingApi, context.Background(), nil, &cloudEvent))
assert.True(t, messagingApiMock.AssertNumberOfCalls(t, "Send", 1))
}