//go:build darwin // +build darwin package secret import ( "testing" "time" "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewSecureEnclaveUnlocker(t *testing.T) { fs := afero.NewMemMapFs() dir := "/tmp/test-se-unlocker" metadata := UnlockerMetadata{ Type: "secure-enclave", CreatedAt: time.Date(2026, 1, 15, 10, 30, 0, 0, time.UTC), Flags: []string{"secure-enclave", "macos"}, } unlocker := NewSecureEnclaveUnlocker(fs, dir, metadata) require.NotNil(t, unlocker, "NewSecureEnclaveUnlocker should return a valid instance") // Test GetType returns correct type assert.Equal(t, seUnlockerType, unlocker.GetType()) // Test GetMetadata returns the metadata we passed in assert.Equal(t, metadata, unlocker.GetMetadata()) // Test GetDirectory returns the directory we passed in assert.Equal(t, dir, unlocker.GetDirectory()) } func TestSecureEnclaveUnlockerImplementsInterface(t *testing.T) { fs := afero.NewMemMapFs() metadata := UnlockerMetadata{ Type: "secure-enclave", CreatedAt: time.Now().UTC(), } unlocker := NewSecureEnclaveUnlocker(fs, "/tmp/test", metadata) // Verify the darwin implementation implements the Unlocker interface var _ Unlocker = unlocker } func TestSecureEnclaveUnlockerGetIDFormat(t *testing.T) { fs := afero.NewMemMapFs() metadata := UnlockerMetadata{ Type: "secure-enclave", CreatedAt: time.Date(2026, 3, 10, 14, 30, 0, 0, time.UTC), } unlocker := NewSecureEnclaveUnlocker(fs, "/tmp/test", metadata) id := unlocker.GetID() // ID should contain the timestamp and "secure-enclave" type assert.Contains(t, id, "2026-03-10.14.30") assert.Contains(t, id, seUnlockerType) } func TestGenerateSEKeyLabel(t *testing.T) { label, err := generateSEKeyLabel("test-vault") require.NoError(t, err) // Label should contain the prefix and vault name assert.Contains(t, label, seKeyLabelPrefix) assert.Contains(t, label, "test-vault") } func TestSecureEnclaveUnlockerGetIdentityMissingFile(t *testing.T) { fs := afero.NewMemMapFs() dir := "/tmp/test-se-unlocker-missing" // Create unlocker directory with metadata but no encrypted key file require.NoError(t, fs.MkdirAll(dir, DirPerms)) metadataJSON := `{ "type": "secure-enclave", "createdAt": "2026-01-15T10:30:00Z", "seKeyLabel": "berlin.sneak.app.secret.se.test", "seKeyHash": "abc123" }` require.NoError(t, afero.WriteFile(fs, dir+"/unlocker-metadata.json", []byte(metadataJSON), FilePerms)) metadata := UnlockerMetadata{ Type: "secure-enclave", CreatedAt: time.Date(2026, 1, 15, 10, 30, 0, 0, time.UTC), } unlocker := NewSecureEnclaveUnlocker(fs, dir, metadata) // GetIdentity should fail because the encrypted longterm key file is missing identity, err := unlocker.GetIdentity() assert.Nil(t, identity) assert.Error(t, err) assert.Contains(t, err.Error(), "failed to read SE-encrypted long-term key") }