Fix scoped gRPC persistence and autosave behavior
This commit is contained in:
@@ -184,6 +184,93 @@ func TestIssueRotateDisableRevokeAndDeleteAPIToken(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueAPITokenAutoSavesWhenSessionSupportsSaving(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
session := &mutableSaveableStubSession{model: vault.Model{}, hasSaveTarget: true}
|
||||
state := State{Session: session}
|
||||
now := time.Date(2026, 3, 29, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
if _, _, err := state.IssueAPIToken("CLI", "grpc-cli", nil, now); err != nil {
|
||||
t.Fatalf("IssueAPIToken() error = %v", err)
|
||||
}
|
||||
|
||||
if session.saveCalls != 1 {
|
||||
t.Fatalf("saveCalls = %d, want 1", session.saveCalls)
|
||||
}
|
||||
if state.Dirty {
|
||||
t.Fatal("Dirty = true, want false after autosave")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueAPITokenDoesNotAutoSaveWithoutSaveTarget(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
session := &mutableSaveableStubSession{model: vault.Model{}}
|
||||
state := State{Session: session}
|
||||
now := time.Date(2026, 3, 29, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
if _, _, err := state.IssueAPIToken("CLI", "grpc-cli", nil, now); err != nil {
|
||||
t.Fatalf("IssueAPIToken() error = %v", err)
|
||||
}
|
||||
|
||||
if session.saveCalls != 0 {
|
||||
t.Fatalf("saveCalls = %d, want 0", session.saveCalls)
|
||||
}
|
||||
if !state.Dirty {
|
||||
t.Fatal("Dirty = false, want true when no save target exists")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueAPITokenDoesNotAutoSaveForRemoteSession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
session := &mutableSaveableStubSession{
|
||||
model: vault.Model{},
|
||||
hasSaveTarget: true,
|
||||
remote: true,
|
||||
}
|
||||
state := State{Session: session}
|
||||
now := time.Date(2026, 3, 29, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
if _, _, err := state.IssueAPIToken("CLI", "grpc-cli", nil, now); err != nil {
|
||||
t.Fatalf("IssueAPIToken() error = %v", err)
|
||||
}
|
||||
|
||||
if session.saveCalls != 0 {
|
||||
t.Fatalf("saveCalls = %d, want 0", session.saveCalls)
|
||||
}
|
||||
if !state.Dirty {
|
||||
t.Fatal("Dirty = false, want true for remote session")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueAPITokenAutoSavesForRemoteSessionWhenEnabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
session := &mutableSaveableStubSession{
|
||||
model: vault.Model{},
|
||||
hasSaveTarget: true,
|
||||
remote: true,
|
||||
}
|
||||
state := State{
|
||||
Session: session,
|
||||
AutoSaveRemote: true,
|
||||
}
|
||||
now := time.Date(2026, 3, 29, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
if _, _, err := state.IssueAPIToken("CLI", "grpc-cli", nil, now); err != nil {
|
||||
t.Fatalf("IssueAPIToken() error = %v", err)
|
||||
}
|
||||
|
||||
if session.saveCalls != 1 {
|
||||
t.Fatalf("saveCalls = %d, want 1", session.saveCalls)
|
||||
}
|
||||
if state.Dirty {
|
||||
t.Fatal("Dirty = true, want false after remote autosave")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteProfilesReturnsVaultProfiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1480,6 +1567,60 @@ func TestCreateGroupPersistsGroupAndMarksDirty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateGroupAutoSavesWhenSessionSupportsSaving(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sess := &mutableSaveableStubSession{model: testVaultModel(), hasSaveTarget: true}
|
||||
state := State{
|
||||
Session: sess,
|
||||
CurrentPath: []string{"Root"},
|
||||
}
|
||||
|
||||
if err := state.CreateGroup("Finance"); err != nil {
|
||||
t.Fatalf("CreateGroup() error = %v", err)
|
||||
}
|
||||
|
||||
if sess.saveCalls != 1 {
|
||||
t.Fatalf("saveCalls = %d, want 1", sess.saveCalls)
|
||||
}
|
||||
if state.Dirty {
|
||||
t.Fatal("Dirty = true, want false after autosave")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateGroupSaveFailureLeavesStateDirty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sess := &mutableSaveableStubSession{
|
||||
model: testVaultModel(),
|
||||
hasSaveTarget: true,
|
||||
saveErr: errors.New("save failed"),
|
||||
}
|
||||
state := State{
|
||||
Session: sess,
|
||||
CurrentPath: []string{"Root"},
|
||||
}
|
||||
|
||||
err := state.CreateGroup("Finance")
|
||||
if err == nil || err.Error() != "save failed" {
|
||||
t.Fatalf("CreateGroup() error = %v, want save failed", err)
|
||||
}
|
||||
if sess.saveCalls != 1 {
|
||||
t.Fatalf("saveCalls = %d, want 1", sess.saveCalls)
|
||||
}
|
||||
if !state.Dirty {
|
||||
t.Fatal("Dirty = false, want true after failed autosave")
|
||||
}
|
||||
|
||||
got, childErr := state.ChildGroups()
|
||||
if childErr != nil {
|
||||
t.Fatalf("ChildGroups() error = %v", childErr)
|
||||
}
|
||||
if !slices.Equal(got, []string{"Finance", "Internet", "Security Office"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want Finance, Internet, Security Office", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateGroupSupportsNestedGroupPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1816,6 +1957,39 @@ func (s *saveableStubSession) Save() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type mutableSaveableStubSession struct {
|
||||
model vault.Model
|
||||
err error
|
||||
saveCalls int
|
||||
saveErr error
|
||||
hasSaveTarget bool
|
||||
remote bool
|
||||
}
|
||||
|
||||
func (s *mutableSaveableStubSession) Current() (vault.Model, error) {
|
||||
if s.err != nil {
|
||||
return vault.Model{}, s.err
|
||||
}
|
||||
return s.model, nil
|
||||
}
|
||||
|
||||
func (s *mutableSaveableStubSession) Replace(model vault.Model) {
|
||||
s.model = model
|
||||
}
|
||||
|
||||
func (s *mutableSaveableStubSession) Save() error {
|
||||
s.saveCalls++
|
||||
return s.saveErr
|
||||
}
|
||||
|
||||
func (s *mutableSaveableStubSession) HasSaveTarget() bool {
|
||||
return s.hasSaveTarget
|
||||
}
|
||||
|
||||
func (s *mutableSaveableStubSession) IsRemote() bool {
|
||||
return s.remote
|
||||
}
|
||||
|
||||
type lifecycleStubSession struct {
|
||||
createCalls int
|
||||
model vault.Model
|
||||
|
||||
Reference in New Issue
Block a user