Files
044afdb1d8 fix(ctxutil): restore password callback hook for embedded age prompts (#3590)
* Initial plan

* fix(ctxutil): restore password callback context hook

Co-authored-by: dominikschulz <1449175+dominikschulz@users.noreply.github.com>

* fix(ctxutil): finalize password callback compatibility

Co-authored-by: dominikschulz <1449175+dominikschulz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Agent <copilot@example.com>
Co-authored-by: dominikschulz <1449175+dominikschulz@users.noreply.github.com>
2026-09-09 21:48:24 +02:00

254 lines
6.0 KiB
Go

package ctxutil
import (
"context"
"testing"
"github.com/gopasspw/gopass/internal/config"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v3"
)
func TestTerminal(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.True(t, IsTerminal(ctx))
assert.True(t, IsTerminal(WithTerminal(ctx, true)))
assert.False(t, IsTerminal(WithTerminal(ctx, false)))
}
func TestInteractive(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.True(t, IsInteractive(ctx))
assert.True(t, IsInteractive(WithInteractive(ctx, true)))
assert.False(t, IsInteractive(WithInteractive(ctx, false)))
}
func TestStdin(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.False(t, IsStdin(ctx))
assert.True(t, IsStdin(WithStdin(ctx, true)))
assert.False(t, IsStdin(WithStdin(ctx, false)))
}
func TestGitCommit(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.True(t, IsGitCommit(ctx))
assert.True(t, IsGitCommit(WithGitCommit(ctx, true)))
assert.False(t, IsGitCommit(WithGitCommit(ctx, false)))
}
func TestAlwaysYes(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.False(t, IsAlwaysYes(ctx))
assert.True(t, IsAlwaysYes(WithAlwaysYes(ctx, true)))
assert.False(t, IsAlwaysYes(WithAlwaysYes(ctx, false)))
}
func TestAlias(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.Empty(t, GetAlias(ctx))
assert.Empty(t, GetAlias(WithAlias(ctx, "")))
}
func TestGitInit(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.True(t, IsGitInit(ctx))
assert.True(t, IsGitInit(WithGitInit(ctx, true)))
assert.False(t, IsGitInit(WithGitInit(ctx, false)))
}
func TestForce(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.False(t, IsForce(ctx))
assert.True(t, IsForce(WithForce(ctx, true)))
assert.False(t, IsForce(WithForce(ctx, false)))
}
func TestCommitMessage(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.Empty(t, GetCommitMessage(ctx))
assert.Equal(t, "foo", GetCommitMessage(WithCommitMessage(ctx, "foo")))
assert.Empty(t, GetCommitMessage(WithCommitMessage(ctx, "")))
}
func TestCommitMessageBody(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
ctx2 := AddToCommitMessageBody(AddToCommitMessageBody(WithCommitMessage(ctx, "foo"), "bar"), "baz")
assert.Equal(t, "foo\n\nbar\nbaz", GetCommitMessageFull(ctx2))
assert.Equal(t, "foo", GetCommitMessage(ctx2))
assert.Equal(t, "bar\nbaz", GetCommitMessageBody(ctx2))
ctx2 = AddToCommitMessageBody(AddToCommitMessageBody(ctx, "bar"), "baz")
assert.Empty(t, GetCommitMessage(ctx2))
assert.Equal(t, "bar\nbaz", GetCommitMessageFull(ctx2))
assert.Equal(t, "bar\nbaz", GetCommitMessageBody(ctx2))
ctx2 = WithCommitMessage(ctx, "foo")
assert.Equal(t, "foo", GetCommitMessage(ctx2))
assert.Equal(t, "foo", GetCommitMessageFull(ctx2))
assert.Empty(t, GetCommitMessageBody(ctx2))
}
func TestComposite(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
ctx = WithTerminal(ctx, false)
ctx = WithInteractive(ctx, false)
ctx = WithStdin(ctx, true)
ctx = WithGitCommit(ctx, false)
ctx = WithAlwaysYes(ctx, true)
ctx = WithEmail(ctx, "foo@bar.com")
ctx = WithUsername(ctx, "foo")
ctx = WithNoNetwork(ctx, true)
ctx = WithCommitMessage(ctx, "foobar")
ctx = WithForce(ctx, true)
ctx = WithGitInit(ctx, false)
assert.False(t, IsTerminal(ctx))
assert.True(t, HasTerminal(ctx))
assert.False(t, IsInteractive(ctx))
assert.True(t, HasInteractive(ctx))
assert.True(t, IsStdin(ctx))
assert.True(t, HasStdin(ctx))
assert.False(t, IsGitCommit(ctx))
assert.True(t, HasGitCommit(ctx))
assert.True(t, IsAlwaysYes(ctx))
assert.True(t, HasAlwaysYes(ctx))
assert.Equal(t, "foo@bar.com", GetEmail(ctx))
assert.Equal(t, "foo", GetUsername(ctx))
assert.True(t, IsNoNetwork(ctx))
assert.True(t, HasNoNetwork(ctx))
assert.Equal(t, "foobar", GetCommitMessage(ctx))
assert.True(t, HasCommitMessage(ctx))
assert.True(t, IsForce(ctx))
assert.True(t, HasForce(ctx))
assert.False(t, IsGitInit(ctx))
assert.True(t, HasGitInit(ctx))
}
func TestGlobalFlags(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
var captured context.Context
cmd := &cli.Command{
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "yes",
Usage: "yes",
},
},
Action: func(c context.Context, cmd *cli.Command) error {
captured = WithGlobalFlags(c, cmd)
return nil
},
}
require.NoError(t, cmd.Run(ctx, []string{"test", "--yes"}))
assert.True(t, IsAlwaysYes(captured))
}
func TestHidden(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.False(t, IsHidden(ctx))
assert.True(t, IsHidden(WithHidden(ctx, true)))
}
func TestSetupRemote(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.False(t, HasSetupRemote(ctx))
assert.True(t, HasSetupRemote(WithSetupRemote(ctx, "https://example.com/repo.git")))
assert.False(t, HasSetupRemote(WithSetupRemote(ctx, "")))
}
func TestPasswordCallback(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
_, err := GetPasswordCallback(ctx)("prompt", false)
require.ErrorIs(t, err, ErrNoCallback)
assert.False(t, HasPasswordCallback(ctx))
ctx = WithPasswordCallback(ctx, func(prompt string, confirm bool) ([]byte, error) {
assert.Equal(t, "prompt", prompt)
assert.True(t, confirm)
return []byte("secret"), nil
})
pw, err := GetPasswordCallback(ctx)("prompt", true)
require.NoError(t, err)
assert.Equal(t, []byte("secret"), pw)
assert.True(t, HasPasswordCallback(ctx))
}
func TestPasswordPurgeCallback(t *testing.T) {
t.Parallel()
ctx := config.NewContextInMemory()
assert.False(t, HasPasswordPurgeCallback(ctx))
assert.NotPanics(t, func() {
GetPasswordPurgeCallback(ctx)("prompt")
})
var purged bool
ctx = WithPasswordPurgeCallback(ctx, func(prompt string) {
assert.Equal(t, "prompt", prompt)
purged = true
})
GetPasswordPurgeCallback(ctx)("prompt")
assert.True(t, purged)
assert.True(t, HasPasswordPurgeCallback(ctx))
}