mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-08-20 11:56:23 +00:00
Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Elias Schneider <login@eliasschneider.com>
73 lines
2.5 KiB
Go
73 lines
2.5 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/libtnb/sqlite"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/pocket-id/pocket-id/backend/internal/common"
|
|
)
|
|
|
|
func TestNewActorsOptsGetPSKUsesStableValue(t *testing.T) {
|
|
opts := NewActorsOpts{
|
|
EnvConfig: &common.EnvConfigSchema{
|
|
EncryptionKey: []byte("test-encryption-key"),
|
|
},
|
|
// Constant value for this test
|
|
InstanceID: "ee05c3eb-8129-47a6-a1c7-849998b6f876",
|
|
}
|
|
|
|
expectedHex := "db09067fa194c3731bf77b6415a1c5d903f03d4557605ba3236b31f6eddfc8d7"
|
|
expected, err := hex.DecodeString(expectedHex)
|
|
require.NoError(t, err)
|
|
|
|
actual, err := opts.getPSK()
|
|
require.NoError(t, err)
|
|
require.Equalf(t, expected, actual, "actual result: %s", actual)
|
|
}
|
|
|
|
// TestNewActorsBackupProvider covers the provider the export and import use to back up and restore the actor host's data.
|
|
// It builds the provider from the same options the actor host uses, so a mismatch between those options and the concrete provider would otherwise only surface at runtime, when an export or import is attempted.
|
|
func TestNewActorsBackupProvider(t *testing.T) {
|
|
// Foreign keys must be enabled, which the provider validates on init and which the application enables on every connection
|
|
dbPath := filepath.Join(t.TempDir(), "pocket-id.db")
|
|
dsn := "file:" + dbPath + "?_txlock=immediate&_pragma=busy_timeout(2500)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(1)"
|
|
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
sqlDB, dbErr := db.DB()
|
|
if dbErr == nil {
|
|
_ = sqlDB.Close()
|
|
}
|
|
})
|
|
|
|
providerOpts, err := ActorsProviderOptions(db, nil)
|
|
require.NoError(t, err)
|
|
|
|
provider, err := NewActorsBackupProvider(t.Context(), providerOpts)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
_ = provider.Close()
|
|
})
|
|
|
|
// Init applies the actor host's schema migrations, so an export also works against a database the actor host has never run against
|
|
var tables int64
|
|
err = db.Raw(`SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name LIKE 'francis_%'`).Scan(&tables).Error
|
|
require.NoError(t, err)
|
|
require.Positive(t, tables, "the provider must create the actor host's own tables")
|
|
|
|
// Even an empty cluster produces a valid backup stream, which an import can restore
|
|
buf := &bytes.Buffer{}
|
|
err = provider.Backup(t.Context(), buf)
|
|
require.NoError(t, err)
|
|
require.Contains(t, buf.String(), "francis-backup")
|
|
|
|
err = provider.Restore(t.Context(), bytes.NewReader(buf.Bytes()))
|
|
require.NoError(t, err)
|
|
}
|