diff --git a/cmd/config/config_test.go b/cmd/config/config_test.go index bd939c5b9..ec1acb07b 100644 --- a/cmd/config/config_test.go +++ b/cmd/config/config_test.go @@ -8,8 +8,10 @@ import ( "strings" "testing" + extcred "github.com/larksuite/cli/extension/credential" "github.com/larksuite/cli/internal/cmdutil" "github.com/larksuite/cli/internal/core" + "github.com/larksuite/cli/internal/credential" "github.com/larksuite/cli/internal/keychain" ) @@ -211,3 +213,62 @@ func TestUpdateExistingProfileWithoutSecret_RejectsAppIDChange(t *testing.T) { t.Fatalf("error = %v, want mention of App Secret", err) } } + +func TestConfigShowRun_PrefersRuntimeCredentialValues(t *testing.T) { + t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) + + multi := &core.MultiAppConfig{ + Apps: []core.AppConfig{{ + Name: "stored", + AppId: "cfg-app", + AppSecret: core.PlainSecret("secret"), + Brand: core.BrandFeishu, + Lang: "zh", + Users: []core.AppUser{{UserOpenId: "ou_cfg", UserName: "Stored User"}}, + }}, + } + if err := core.SaveMultiAppConfig(multi); err != nil { + t.Fatal(err) + } + + f, stdout, stderr, _ := cmdutil.TestFactory(t, &core.CliConfig{AppID: "cfg-app", AppSecret: "secret", Brand: core.BrandFeishu}) + f.Credential = credential.NewCredentialProvider( + []extcred.Provider{&stubStrictModeProvider{ + name: "env", + account: &extcred.Account{ + AppID: "env-app", + AppSecret: "env-secret", + Brand: string(core.BrandLark), + OpenID: "ou_env", + }, + }}, + nil, + nil, + nil, + ) + f.Config = func() (*core.CliConfig, error) { + cfg, err := f.Credential.ResolveAccount(context.Background()) + if err != nil { + return nil, err + } + cfg.UserName = "Env User" + return cfg, nil + } + + if err := configShowRun(&ConfigShowOptions{Factory: f}); err != nil { + t.Fatalf("configShowRun() error = %v", err) + } + + if !strings.Contains(stdout.String(), `"appId": "env-app"`) { + t.Fatalf("stdout = %q, want runtime appId", stdout.String()) + } + if !strings.Contains(stdout.String(), `"brand": "lark"`) { + t.Fatalf("stdout = %q, want runtime brand", stdout.String()) + } + if !strings.Contains(stdout.String(), `"users": "Env User (ou_env)"`) { + t.Fatalf("stdout = %q, want runtime user", stdout.String()) + } + if !strings.Contains(stderr.String(), core.GetConfigPath()) { + t.Fatalf("stderr = %q, want config path", stderr.String()) + } +} diff --git a/cmd/config/default_as_test.go b/cmd/config/default_as_test.go new file mode 100644 index 000000000..8c7916ff2 --- /dev/null +++ b/cmd/config/default_as_test.go @@ -0,0 +1,57 @@ +// Copyright (c) 2026 Lark Technologies Pte. Ltd. +// SPDX-License-Identifier: MIT + +package config + +import ( + "context" + "strings" + "testing" + + extcred "github.com/larksuite/cli/extension/credential" + "github.com/larksuite/cli/internal/cmdutil" + "github.com/larksuite/cli/internal/core" + "github.com/larksuite/cli/internal/credential" +) + +func TestDefaultAs_Show_PrefersRuntimeCredentialValue(t *testing.T) { + setupStrictModeTestConfig(t) + + multi, err := core.LoadMultiAppConfig() + if err != nil { + t.Fatal(err) + } + multi.Apps[0].DefaultAs = "auto" + if err := core.SaveMultiAppConfig(multi); err != nil { + t.Fatal(err) + } + + f, stdout, _, _ := cmdutil.TestFactory(t, &core.CliConfig{AppID: "test-app", AppSecret: "secret", DefaultAs: "auto"}) + f.Credential = credential.NewCredentialProvider( + []extcred.Provider{&stubStrictModeProvider{ + name: "env", + account: &extcred.Account{ + AppID: "env-app", + AppSecret: "env-secret", + Brand: string(core.BrandFeishu), + DefaultAs: extcred.IdentityUser, + }, + }}, + nil, + nil, + nil, + ) + f.Config = func() (*core.CliConfig, error) { + return f.Credential.ResolveAccount(context.Background()) + } + + cmd := NewCmdConfigDefaultAs(f) + cmd.SetArgs([]string{}) + if err := cmd.Execute(); err != nil { + t.Fatal(err) + } + + if !strings.Contains(stdout.String(), "default-as: user") { + t.Fatalf("output = %q, want runtime default-as", stdout.String()) + } +} diff --git a/cmd/config/show.go b/cmd/config/show.go index 81edcdabb..9572481a6 100644 --- a/cmd/config/show.go +++ b/cmd/config/show.go @@ -50,22 +50,64 @@ func configShowRun(opts *ConfigShowOptions) error { fmt.Fprintln(f.IOStreams.ErrOut, "No active profile found.") return nil } - users := "(no logged-in users)" - if len(app.Users) > 0 { - var userStrs []string - for _, u := range app.Users { - userStrs = append(userStrs, fmt.Sprintf("%s (%s)", u.UserName, u.UserOpenId)) + runtime := runtimeConfigSnapshot(f) + profile := app.ProfileName() + appID := app.AppId + brand := string(app.Brand) + users := formatStoredUsers(app.Users) + + if runtime != nil { + if runtime.ProfileName != "" { + profile = runtime.ProfileName + } + if runtime.AppID != "" { + appID = runtime.AppID + } + if runtime.Brand != "" { + brand = string(runtime.Brand) + } + if runtime.UserOpenId != "" { + users = formatRuntimeUser(runtime.UserName, runtime.UserOpenId) } - users = strings.Join(userStrs, ", ") } + output.PrintJson(f.IOStreams.Out, map[string]interface{}{ - "profile": app.ProfileName(), - "appId": app.AppId, + "profile": profile, + "appId": appID, "appSecret": "****", - "brand": app.Brand, + "brand": brand, "lang": app.Lang, "users": users, }) fmt.Fprintf(f.IOStreams.ErrOut, "\nConfig file path: %s\n", core.GetConfigPath()) return nil } + +func runtimeConfigSnapshot(f *cmdutil.Factory) *core.CliConfig { + if f == nil || f.Config == nil { + return nil + } + cfg, err := f.Config() + if err != nil { + return nil + } + return cfg +} + +func formatStoredUsers(users []core.AppUser) string { + if len(users) == 0 { + return "(no logged-in users)" + } + var userStrs []string + for _, u := range users { + userStrs = append(userStrs, formatRuntimeUser(u.UserName, u.UserOpenId)) + } + return strings.Join(userStrs, ", ") +} + +func formatRuntimeUser(name, openID string) string { + if name == "" { + return openID + } + return fmt.Sprintf("%s (%s)", name, openID) +}