package api import ( auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/gen/go/audit/v1" "github.com/bufbuild/protovalidate-go" "github.com/stretchr/testify/assert" "testing" ) func Test_RoutableAuditEvent(t *testing.T) { validator, err := protovalidate.New() assert.NoError(t, err) newEvent := func() auditV1.RoutableAuditEvent { return auditV1.RoutableAuditEvent{ OperationName: "stackit.resource-manager.v1.organizations.create", Visibility: auditV1.Visibility_VISIBILITY_PUBLIC, ObjectIdentifier: &auditV1.ObjectIdentifier{ Identifier: "14f7aa86-77ba-4d77-a091-a2cf3395a221", Type: string(ObjectTypeProject), }, Data: &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &auditV1.UnencryptedData{ Data: []byte("data"), ProtobufType: "audit.v1.AuditLogEntry", }}} } t.Run("valid event", func(t *testing.T) { event := newEvent() err := validator.Validate(&event) assert.NoError(t, err) }) t.Run("empty operation name", func(t *testing.T) { event := newEvent() event.OperationName = "" err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - operation_name: value is required [required]") }) t.Run("invalid operation name", func(t *testing.T) { event := newEvent() event.OperationName = "stackit.resource-manager.v1.INVALID.organizations.create" err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - operation_name: value does not match regex pattern `^stackit\\.[a-z0-9-]+\\.(?:v[0-9]+\\.)?(?:[a-z0-9-.]+\\.)?[a-z0-9-]+$` [string.pattern]") }) t.Run("visibility invalid", func(t *testing.T) { event := newEvent() event.Visibility = -1 err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - visibility: value must be one of the defined enum values [enum.defined_only]") }) t.Run("visibility unspecified", func(t *testing.T) { event := newEvent() event.Visibility = auditV1.Visibility_VISIBILITY_UNSPECIFIED err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - visibility: value is required [required]") }) t.Run("object identifier nil", func(t *testing.T) { event := newEvent() event.ObjectIdentifier = nil err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - object_identifier: value is required [required]") }) t.Run("object identifier id empty", func(t *testing.T) { event := newEvent() event.ObjectIdentifier.Identifier = "" err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - object_identifier.identifier: value is required [required]") }) t.Run("object identifier id not uuid", func(t *testing.T) { event := newEvent() event.ObjectIdentifier.Identifier = "invalid" err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - object_identifier.identifier: value must be a valid UUID [string.uuid]") }) t.Run("object identifier type empty", func(t *testing.T) { event := newEvent() event.ObjectIdentifier.Type = "" err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - object_identifier.type: value is required [required]") }) t.Run("data nil", func(t *testing.T) { event := newEvent() event.Data = nil err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - data: exactly one field is required in oneof [required]") }) t.Run("data empty", func(t *testing.T) { event := newEvent() event.Data = &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &auditV1.UnencryptedData{ Data: []byte{}, ProtobufType: "audit.v1.AuditLogEntry", }} err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - unencrypted_data.data: value is required [required]") }) t.Run("data protobuf type empty", func(t *testing.T) { event := newEvent() event.Data = &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &auditV1.UnencryptedData{ Data: []byte("data"), ProtobufType: "", }} err := validator.Validate(&event) assert.EqualError(t, err, "validation error:\n - unencrypted_data.protobuf_type: value is required [required]") }) }