vault/audit/options_test.go

510 lines
12 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package audit
import (
"testing"
"time"
"github.com/stretchr/testify/require"
)
// TestOptions_withFormat exercises withFormat option to ensure it performs as expected.
func TestOptions_withFormat(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value string
IsErrorExpected bool
ExpectedErrorMessage string
ExpectedValue format
}{
"empty": {
Value: "",
IsErrorExpected: false,
ExpectedValue: format(""),
},
"whitespace": {
Value: " ",
IsErrorExpected: false,
ExpectedValue: format(""),
},
"invalid-test": {
Value: "test",
IsErrorExpected: true,
ExpectedErrorMessage: "invalid format \"test\": invalid internal parameter",
},
"valid-json": {
Value: "json",
IsErrorExpected: false,
ExpectedValue: jsonFormat,
},
"valid-jsonx": {
Value: "jsonx",
IsErrorExpected: false,
ExpectedValue: jsonxFormat,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withFormat(tc.Value)
err := applyOption(opts)
switch {
case tc.IsErrorExpected:
require.Error(t, err)
require.EqualError(t, err, tc.ExpectedErrorMessage)
default:
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withFormat)
}
})
}
}
// TestOptions_withSubtype exercises withSubtype option to ensure it performs as expected.
func TestOptions_withSubtype(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value string
IsErrorExpected bool
ExpectedErrorMessage string
ExpectedValue subtype
}{
"empty": {
Value: "",
IsErrorExpected: true,
ExpectedErrorMessage: "subtype cannot be empty",
},
"whitespace": {
Value: " ",
IsErrorExpected: true,
ExpectedErrorMessage: "subtype cannot be empty",
},
"valid": {
Value: "AuditResponse",
IsErrorExpected: false,
ExpectedValue: ResponseType,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withSubtype(tc.Value)
err := applyOption(opts)
switch {
case tc.IsErrorExpected:
require.Error(t, err)
require.EqualError(t, err, tc.ExpectedErrorMessage)
default:
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withSubtype)
}
})
}
}
// TestOptions_withNow exercises withNow option to ensure it performs as expected.
func TestOptions_withNow(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value time.Time
IsErrorExpected bool
ExpectedErrorMessage string
ExpectedValue time.Time
}{
"default-time": {
Value: time.Time{},
IsErrorExpected: true,
ExpectedErrorMessage: "cannot specify 'now' to be the zero time instant",
},
"valid-time": {
Value: time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local),
IsErrorExpected: false,
ExpectedValue: time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local),
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withNow(tc.Value)
err := applyOption(opts)
switch {
case tc.IsErrorExpected:
require.Error(t, err)
require.EqualError(t, err, tc.ExpectedErrorMessage)
default:
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withNow)
}
})
}
}
// TestOptions_withID exercises withID option to ensure it performs as expected.
func TestOptions_withID(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value string
IsErrorExpected bool
ExpectedErrorMessage string
ExpectedValue string
}{
"empty": {
Value: "",
IsErrorExpected: true,
ExpectedErrorMessage: "id cannot be empty",
},
"whitespace": {
Value: " ",
IsErrorExpected: true,
ExpectedErrorMessage: "id cannot be empty",
},
"valid": {
Value: "test",
IsErrorExpected: false,
ExpectedValue: "test",
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withID(tc.Value)
err := applyOption(opts)
switch {
case tc.IsErrorExpected:
require.Error(t, err)
require.EqualError(t, err, tc.ExpectedErrorMessage)
default:
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withID)
}
})
}
}
// TestOptions_withPrefix exercises withPrefix option to ensure it performs as expected.
func TestOptions_withPrefix(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value string
IsErrorExpected bool
ExpectedErrorMessage string
ExpectedValue string
}{
"empty": {
Value: "",
IsErrorExpected: false,
ExpectedValue: "",
},
"whitespace": {
Value: " ",
IsErrorExpected: false,
ExpectedValue: " ",
},
"valid": {
Value: "test",
IsErrorExpected: false,
ExpectedValue: "test",
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withPrefix(tc.Value)
err := applyOption(opts)
switch {
case tc.IsErrorExpected:
require.Error(t, err)
require.EqualError(t, err, tc.ExpectedErrorMessage)
default:
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withPrefix)
}
})
}
}
// TestOptions_withRaw exercises withRaw option to ensure it performs as expected.
func TestOptions_withRaw(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value bool
ExpectedValue bool
}{
"true": {
Value: true,
ExpectedValue: true,
},
"false": {
Value: false,
ExpectedValue: false,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withRaw(tc.Value)
err := applyOption(opts)
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withRaw)
})
}
}
// TestOptions_withElision exercises withElision option to ensure it performs as expected.
func TestOptions_withElision(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value bool
ExpectedValue bool
}{
"true": {
Value: true,
ExpectedValue: true,
},
"false": {
Value: false,
ExpectedValue: false,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withElision(tc.Value)
err := applyOption(opts)
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withElision)
})
}
}
// TestOptions_withHMACAccessor exercises withHMACAccessor option to ensure it performs as expected.
func TestOptions_withHMACAccessor(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value bool
ExpectedValue bool
}{
"true": {
Value: true,
ExpectedValue: true,
},
"false": {
Value: false,
ExpectedValue: false,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withHMACAccessor(tc.Value)
err := applyOption(opts)
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withHMACAccessor)
})
}
}
// TestOptions_withOmitTime exercises withOmitTime option to ensure it performs as expected.
func TestOptions_withOmitTime(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Value bool
ExpectedValue bool
}{
"true": {
Value: true,
ExpectedValue: true,
},
"false": {
Value: false,
ExpectedValue: false,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts := &options{}
applyOption := withOmitTime(tc.Value)
err := applyOption(opts)
require.NoError(t, err)
require.Equal(t, tc.ExpectedValue, opts.withOmitTime)
})
}
}
// TestOptions_Default exercises getDefaultOptions to assert the default values.
func TestOptions_Default(t *testing.T) {
t.Parallel()
opts := getDefaultOptions()
require.NotNil(t, opts)
require.True(t, time.Now().After(opts.withNow))
require.False(t, opts.withNow.IsZero())
}
// TestOptions_Opts exercises GetOpts with various option values.
func TestOptions_Opts(t *testing.T) {
t.Parallel()
tests := map[string]struct {
opts []option
IsErrorExpected bool
ExpectedErrorMessage string
ExpectedID string
ExpectedSubtype subtype
ExpectedFormat format
IsNowExpected bool
ExpectedNow time.Time
}{
"nil-options": {
opts: nil,
IsErrorExpected: false,
IsNowExpected: true,
ExpectedFormat: jsonFormat,
},
"empty-options": {
opts: []option{},
IsErrorExpected: false,
IsNowExpected: true,
ExpectedFormat: jsonFormat,
},
"with-multiple-valid-id": {
opts: []option{
withID("qwerty"),
withID("juan"),
},
IsErrorExpected: false,
ExpectedID: "juan",
IsNowExpected: true,
ExpectedFormat: jsonFormat,
},
"with-multiple-valid-subtype": {
opts: []option{
withSubtype("AuditRequest"),
withSubtype("AuditResponse"),
},
IsErrorExpected: false,
ExpectedSubtype: ResponseType,
IsNowExpected: true,
ExpectedFormat: jsonFormat,
},
"with-multiple-valid-format": {
opts: []option{
withFormat("json"),
withFormat("jsonx"),
},
IsErrorExpected: false,
ExpectedFormat: jsonxFormat,
IsNowExpected: true,
},
"with-multiple-valid-now": {
opts: []option{
withNow(time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local)),
withNow(time.Date(2023, time.July, 4, 13, 3, 0, 0, time.Local)),
},
IsErrorExpected: false,
ExpectedNow: time.Date(2023, time.July, 4, 13, 3, 0, 0, time.Local),
IsNowExpected: false,
ExpectedFormat: jsonFormat,
},
"with-multiple-valid-then-invalid-now": {
opts: []option{
withNow(time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local)),
withNow(time.Time{}),
},
IsErrorExpected: true,
ExpectedErrorMessage: "cannot specify 'now' to be the zero time instant",
ExpectedFormat: jsonFormat,
},
"with-multiple-valid-options": {
opts: []option{
withID("qwerty"),
withSubtype("AuditRequest"),
withFormat("json"),
withNow(time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local)),
},
IsErrorExpected: false,
ExpectedID: "qwerty",
ExpectedSubtype: RequestType,
ExpectedFormat: jsonFormat,
ExpectedNow: time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local),
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
opts, err := getOpts(tc.opts...)
switch {
case tc.IsErrorExpected:
require.Error(t, err)
require.EqualError(t, err, tc.ExpectedErrorMessage)
default:
require.NotNil(t, opts)
require.NoError(t, err)
require.Equal(t, tc.ExpectedID, opts.withID)
require.Equal(t, tc.ExpectedSubtype, opts.withSubtype)
require.Equal(t, tc.ExpectedFormat, opts.withFormat)
switch {
case tc.IsNowExpected:
require.True(t, time.Now().After(opts.withNow))
require.False(t, opts.withNow.IsZero())
default:
require.Equal(t, tc.ExpectedNow, opts.withNow)
}
}
})
}
}