diff --git a/internal/cli/integration_test.go b/internal/cli/integration_test.go index fb9f598..9474884 100644 --- a/internal/cli/integration_test.go +++ b/internal/cli/integration_test.go @@ -52,11 +52,12 @@ func TestMain(m *testing.M) { // all functionality of the secret manager using a real filesystem in a temporary directory. // This test serves as both validation and documentation of the program's behavior. func TestSecretManagerIntegration(t *testing.T) { - // Enable debug logging to diagnose issues - t.Setenv("GODEBUG", "berlin.sneak.pkg.secret") - - // Reinitialize debug logging to pick up the environment variable change - secret.InitDebugLogging() + // Only enable debug logging if running with -v flag + if testing.Verbose() { + t.Setenv("GODEBUG", "berlin.sneak.pkg.secret") + // Reinitialize debug logging to pick up the environment variable change + secret.InitDebugLogging() + } // Test configuration testMnemonic := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" @@ -266,7 +267,7 @@ func TestSecretManagerIntegration(t *testing.T) { // Test 26: Large secret values // Purpose: Test with large secret values (e.g., certificates) // Expected: Proper storage and retrieval - test26LargeSecrets(t, tempDir, secretPath, testMnemonic, runSecret, runSecretWithEnv) + test26LargeSecrets(t, tempDir, secretPath, testMnemonic, runSecret, runSecretWithEnv, runSecretWithStdin) // Test 27: Special characters in values // Purpose: Test secrets with newlines, unicode, binary data @@ -380,8 +381,8 @@ func test01Initialize(t *testing.T, tempDir, testMnemonic, testPassphrase string t.Logf("Parsed metadata: %+v", metadata) // Verify metadata fields - assert.Equal(t, float64(0), metadata["derivation_index"], "first vault should have index 0") - assert.Contains(t, metadata, "public_key_hash", "should contain public key hash") + assert.Equal(t, float64(0), metadata["derivationIndex"], "first vault should have index 0") + assert.Contains(t, metadata, "publicKeyHash", "should contain public key hash") assert.Contains(t, metadata, "createdAt", "should contain creation timestamp") // Verify the longterm.age file in passphrase unlocker @@ -411,8 +412,8 @@ func test02ListVaults(t *testing.T, runSecret func(...string) (string, error)) { require.NoError(t, err, "JSON output should be valid") // Verify current vault - currentVault, ok := response["current_vault"] - require.True(t, ok, "response should contain current_vault") + currentVault, ok := response["currentVault"] + require.True(t, ok, "response should contain currentVault") assert.Equal(t, "default", currentVault, "current vault should be default") // Verify vaults list @@ -520,14 +521,14 @@ func test04ImportMnemonic(t *testing.T, tempDir, testMnemonic, testPassphrase st require.NoError(t, err, "vault metadata should be valid JSON") // Work vault should have a different derivation index than default (0) - derivIndex, ok := metadata["derivation_index"].(float64) - require.True(t, ok, "derivation_index should be a number") + derivIndex, ok := metadata["derivationIndex"].(float64) + require.True(t, ok, "derivationIndex should be a number") assert.NotEqual(t, float64(0), derivIndex, "work vault should have non-zero derivation index") // Verify public key hash is stored - assert.Contains(t, metadata, "public_key_hash", "should contain public key hash") - pubKeyHash, ok := metadata["public_key_hash"].(string) - require.True(t, ok, "public_key_hash should be a string") + assert.Contains(t, metadata, "publicKeyHash", "should contain public key hash") + pubKeyHash, ok := metadata["publicKeyHash"].(string) + require.True(t, ok, "publicKeyHash should be a string") assert.NotEmpty(t, pubKeyHash, "public key hash should not be empty") } @@ -876,8 +877,8 @@ func test11ListSecrets(t *testing.T, testMnemonic string, runSecret func(...stri var listResponse struct { Secrets []struct { Name string `json:"name"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` } `json:"secrets"` Filter string `json:"filter,omitempty"` } @@ -1377,7 +1378,7 @@ func test19DisasterRecovery(t *testing.T, tempDir, secretPath, testMnemonic stri require.NoError(t, err, "read vault metadata") var metadata struct { - DerivationIndex uint32 `json:"derivation_index"` + DerivationIndex uint32 `json:"derivationIndex"` } err = json.Unmarshal(metadataBytes, &metadata) require.NoError(t, err, "parse vault metadata") @@ -1531,7 +1532,7 @@ func test22JSONOutput(t *testing.T, runSecret func(...string) (string, error)) { err = json.Unmarshal([]byte(output), &vaultListResponse) require.NoError(t, err, "vault list JSON should be valid") assert.Contains(t, vaultListResponse, "vaults", "should have vaults key") - assert.Contains(t, vaultListResponse, "current_vault", "should have current_vault key") + assert.Contains(t, vaultListResponse, "currentVault", "should have currentVault key") // Test secret list --json (already tested in test 11) @@ -1687,7 +1688,7 @@ func test25ConcurrentOperations(t *testing.T, testMnemonic string, runSecret fun // to avoid conflicts, but reads should always work } -func test26LargeSecrets(t *testing.T, tempDir, secretPath, testMnemonic string, runSecret func(...string) (string, error), runSecretWithEnv func(map[string]string, ...string) (string, error)) { +func test26LargeSecrets(t *testing.T, tempDir, secretPath, testMnemonic string, runSecret func(...string) (string, error), runSecretWithEnv func(map[string]string, ...string) (string, error), runSecretWithStdin func(string, map[string]string, ...string) (string, error)) { // Make sure we're in default vault _, err := runSecret("vault", "select", "default") require.NoError(t, err, "vault select should succeed") @@ -1700,16 +1701,10 @@ func test26LargeSecrets(t *testing.T, tempDir, secretPath, testMnemonic string, assert.Greater(t, len(largeValue), 10000, "should be > 10KB") // Add large secret - cmd := exec.Command(secretPath, "add", "large/secret", "--force") - cmd.Env = []string{ - fmt.Sprintf("SB_SECRET_STATE_DIR=%s", tempDir), - fmt.Sprintf("SB_SECRET_MNEMONIC=%s", testMnemonic), - fmt.Sprintf("PATH=%s", os.Getenv("PATH")), - fmt.Sprintf("HOME=%s", os.Getenv("HOME")), - } - cmd.Stdin = strings.NewReader(largeValue) - output, err := cmd.CombinedOutput() - require.NoError(t, err, "add large secret should succeed: %s", string(output)) + _, err = runSecretWithStdin(largeValue, map[string]string{ + "SB_SECRET_MNEMONIC": testMnemonic, + }, "add", "large/secret", "--force") + require.NoError(t, err, "add large secret should succeed") // Retrieve and verify retrievedValue, err := runSecretWithEnv(map[string]string{ @@ -1725,15 +1720,9 @@ BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTgwMjI4MTQwMzQ5WhcNMjgwMjI2MTQwMzQ5WjBF -----END CERTIFICATE-----` - cmd = exec.Command(secretPath, "add", "cert/test", "--force") - cmd.Env = []string{ - fmt.Sprintf("SB_SECRET_STATE_DIR=%s", tempDir), - fmt.Sprintf("SB_SECRET_MNEMONIC=%s", testMnemonic), - fmt.Sprintf("PATH=%s", os.Getenv("PATH")), - fmt.Sprintf("HOME=%s", os.Getenv("HOME")), - } - cmd.Stdin = strings.NewReader(certValue) - _, err = cmd.CombinedOutput() + _, err = runSecretWithStdin(certValue, map[string]string{ + "SB_SECRET_MNEMONIC": testMnemonic, + }, "add", "cert/test", "--force") require.NoError(t, err, "add certificate should succeed") // Retrieve and verify certificate @@ -1821,10 +1810,10 @@ func test28VaultMetadata(t *testing.T, tempDir string) { require.NoError(t, err, "default vault metadata should be valid JSON") // Verify required fields - assert.Equal(t, float64(0), defaultMetadata["derivation_index"]) + assert.Equal(t, float64(0), defaultMetadata["derivationIndex"]) assert.Contains(t, defaultMetadata, "createdAt") - assert.Contains(t, defaultMetadata, "public_key_hash") - assert.Contains(t, defaultMetadata, "mnemonic_family_hash") + assert.Contains(t, defaultMetadata, "publicKeyHash") + assert.Contains(t, defaultMetadata, "mnemonicFamilyHash") // Check work vault metadata workMetadataPath := filepath.Join(tempDir, "vaults.d", "work", "vault-metadata.json") @@ -1836,12 +1825,12 @@ func test28VaultMetadata(t *testing.T, tempDir string) { require.NoError(t, err, "work vault metadata should be valid JSON") // Work vault should have different derivation index - workIndex := workMetadata["derivation_index"].(float64) + workIndex := workMetadata["derivationIndex"].(float64) assert.NotEqual(t, float64(0), workIndex, "work vault should have non-zero derivation index") - // Both vaults created with same mnemonic should have same mnemonic_family_hash - assert.Equal(t, defaultMetadata["mnemonic_family_hash"], workMetadata["mnemonic_family_hash"], - "vaults from same mnemonic should have same mnemonic_family_hash") + // Both vaults created with same mnemonic should have same mnemonicFamilyHash + assert.Equal(t, defaultMetadata["mnemonicFamilyHash"], workMetadata["mnemonicFamilyHash"], + "vaults from same mnemonic should have same mnemonicFamilyHash") } func test29SymlinkHandling(t *testing.T, tempDir, secretPath, testMnemonic string) { @@ -2000,14 +1989,14 @@ func test31EnvMnemonicUsesVaultDerivationIndex(t *testing.T, tempDir, secretPath var defaultMetadata map[string]interface{} err := json.Unmarshal(defaultMetadataBytes, &defaultMetadata) require.NoError(t, err, "default vault metadata should be valid JSON") - assert.Equal(t, float64(0), defaultMetadata["derivation_index"], "default vault should have index 0") + assert.Equal(t, float64(0), defaultMetadata["derivationIndex"], "default vault should have index 0") workMetadataPath := filepath.Join(tempDir, "vaults.d", "work", "vault-metadata.json") workMetadataBytes := readFile(t, workMetadataPath) var workMetadata map[string]interface{} err = json.Unmarshal(workMetadataBytes, &workMetadata) require.NoError(t, err, "work vault metadata should be valid JSON") - assert.Equal(t, float64(1), workMetadata["derivation_index"], "work vault should have index 1") + assert.Equal(t, float64(1), workMetadata["derivationIndex"], "work vault should have index 1") // Switch to work vault _, err = runSecret("vault", "select", "work") diff --git a/internal/cli/vault.go b/internal/cli/vault.go index 1b51ee5..68d7cde 100644 --- a/internal/cli/vault.go +++ b/internal/cli/vault.go @@ -109,8 +109,8 @@ func (cli *Instance) ListVaults(cmd *cobra.Command, jsonOutput bool) error { } result := map[string]interface{}{ - "vaults": vaults, - "current_vault": currentVault, + "vaults": vaults, + "currentVault": currentVault, } jsonBytes, err := json.MarshalIndent(result, "", " ") diff --git a/internal/secret/pgpunlock_test.go b/internal/secret/pgpunlock_test.go index e0ad3ee..308a9c2 100644 --- a/internal/secret/pgpunlock_test.go +++ b/internal/secret/pgpunlock_test.go @@ -360,9 +360,9 @@ Passphrase: ` + testPassphrase + ` var metadata struct { ID string `json:"id"` Type string `json:"type"` - CreatedAt time.Time `json:"created_at"` + CreatedAt time.Time `json:"createdAt"` Flags []string `json:"flags"` - GPGKeyID string `json:"gpg_key_id"` + GPGKeyID string `json:"gpgKeyId"` } if err := json.Unmarshal(metadataBytes, &metadata); err != nil { @@ -399,7 +399,7 @@ Passphrase: ` + testPassphrase + ` // Create PGP metadata with GPG key ID type PGPUnlockerMetadata struct { secret.UnlockerMetadata - GPGKeyID string `json:"gpg_key_id"` + GPGKeyID string `json:"gpgKeyId"` } pgpMetadata := PGPUnlockerMetadata{