mirror of
https://github.com/fleetdm/fleet
synced 2026-05-20 15:38:39 +00:00
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #38234 Minor developer experience improvement for tests using MySQL. This is a code review follow up.
108 lines
3.4 KiB
Go
108 lines
3.4 KiB
Go
// Package testutils provides shared test utilities for the activity bounded context.
|
|
package testutils
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
common_mysql "github.com/fleetdm/fleet/v4/server/platform/mysql"
|
|
mysql_testing_utils "github.com/fleetdm/fleet/v4/server/platform/mysql/testing_utils"
|
|
"github.com/go-kit/log"
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestDB holds the database connection for tests.
|
|
type TestDB struct {
|
|
DB *sqlx.DB
|
|
Logger log.Logger
|
|
}
|
|
|
|
// SetupTestDB creates a test database with the Fleet schema loaded.
|
|
func SetupTestDB(t *testing.T, testNamePrefix string) *TestDB {
|
|
t.Helper()
|
|
|
|
testName, opts := mysql_testing_utils.ProcessOptions(t, &mysql_testing_utils.DatastoreTestOptions{
|
|
UniqueTestName: testNamePrefix + "_" + t.Name(),
|
|
})
|
|
|
|
mysql_testing_utils.LoadDefaultSchema(t, testName, opts)
|
|
config := mysql_testing_utils.MysqlTestConfig(testName)
|
|
db, err := common_mysql.NewDB(config, &common_mysql.DBOptions{}, "")
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(func() { db.Close() })
|
|
|
|
return &TestDB{
|
|
DB: db,
|
|
Logger: log.NewNopLogger(),
|
|
}
|
|
}
|
|
|
|
// Conns returns DBConnections for creating a datastore.
|
|
func (tdb *TestDB) Conns() *common_mysql.DBConnections {
|
|
return &common_mysql.DBConnections{Primary: tdb.DB, Replica: tdb.DB}
|
|
}
|
|
|
|
// TruncateTables clears the activities and users tables.
|
|
func (tdb *TestDB) TruncateTables(t *testing.T) {
|
|
t.Helper()
|
|
mysql_testing_utils.TruncateTables(t, tdb.DB, tdb.Logger, nil, "activities", "users")
|
|
}
|
|
|
|
// InsertUser creates a user in the database and returns the user ID.
|
|
func (tdb *TestDB) InsertUser(t *testing.T, name, email string) uint {
|
|
t.Helper()
|
|
ctx := t.Context()
|
|
|
|
result, err := tdb.DB.ExecContext(ctx, `
|
|
INSERT INTO users (name, email, password, salt, created_at, updated_at)
|
|
VALUES (?, ?, 'password', 'salt', NOW(), NOW())
|
|
`, name, email)
|
|
require.NoError(t, err)
|
|
|
|
id, err := result.LastInsertId()
|
|
require.NoError(t, err)
|
|
return uint(id)
|
|
}
|
|
|
|
// InsertActivity creates an activity in the database and returns the activity ID.
|
|
// Pass nil for userID to create a system activity (no associated user).
|
|
func (tdb *TestDB) InsertActivity(t *testing.T, userID *uint, activityType string, details map[string]any) uint {
|
|
t.Helper()
|
|
return tdb.InsertActivityWithTime(t, userID, activityType, details, time.Now().UTC())
|
|
}
|
|
|
|
// InsertActivityWithTime creates an activity with a specific timestamp.
|
|
// Pass nil for userID to create a system activity (no associated user).
|
|
func (tdb *TestDB) InsertActivityWithTime(t *testing.T, userID *uint, activityType string, details map[string]any, createdAt time.Time) uint {
|
|
t.Helper()
|
|
ctx := t.Context()
|
|
|
|
detailsJSON, err := json.Marshal(details)
|
|
require.NoError(t, err)
|
|
|
|
var userName *string
|
|
var userEmail string // NOT NULL DEFAULT '' in schema
|
|
if userID != nil {
|
|
var user struct {
|
|
Name string `db:"name"`
|
|
Email string `db:"email"`
|
|
}
|
|
err = sqlx.GetContext(ctx, tdb.DB, &user, "SELECT name, email FROM users WHERE id = ?", *userID)
|
|
require.NoError(t, err)
|
|
userName = &user.Name
|
|
userEmail = user.Email
|
|
}
|
|
|
|
result, err := tdb.DB.ExecContext(ctx, `
|
|
INSERT INTO activities (user_id, user_name, user_email, activity_type, details, created_at, host_only, streamed)
|
|
VALUES (?, ?, ?, ?, ?, ?, false, false)
|
|
`, userID, userName, userEmail, activityType, detailsJSON, createdAt)
|
|
require.NoError(t, err)
|
|
|
|
id, err := result.LastInsertId()
|
|
require.NoError(t, err)
|
|
return uint(id)
|
|
}
|