TestHandleRootError_AuthConfigWireGolden is the wire-consistency regression baseline for auth/config errors: it pins the typed envelope and exit code the dispatcher produces for the two source-of-truth shapes, which are constructed typed at their origin in internal/auth and internal/core.
(t *testing.T)
| 307 | // dispatcher produces for the two source-of-truth shapes, which are constructed |
| 308 | // typed at their origin in internal/auth and internal/core. |
| 309 | func TestHandleRootError_AuthConfigWireGolden(t *testing.T) { |
| 310 | t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) |
| 311 | |
| 312 | t.Run("token missing exits 3 with token_missing authentication envelope", func(t *testing.T) { |
| 313 | f, _, _, _ := cmdutil.TestFactory(t, nil) |
| 314 | errOut := &bytes.Buffer{} |
| 315 | f.IOStreams.ErrOut = errOut |
| 316 | |
| 317 | exit := handleRootError(f, internalauth.NewNeedUserAuthorizationError("u_golden")) |
| 318 | if exit != int(output.ExitAuth) { |
| 319 | t.Errorf("exit = %d, want %d (ExitAuth)", exit, int(output.ExitAuth)) |
| 320 | } |
| 321 | |
| 322 | errObj := decodeErrorEnvelope(t, errOut.Bytes()) |
| 323 | if got := errObj["type"]; got != "authentication" { |
| 324 | t.Errorf("error.type = %v, want %q", got, "authentication") |
| 325 | } |
| 326 | if got := errObj["subtype"]; got != "token_missing" { |
| 327 | t.Errorf("error.subtype = %v, want %q", got, "token_missing") |
| 328 | } |
| 329 | if got, _ := errObj["message"].(string); !strings.Contains(got, "need_user_authorization") { |
| 330 | t.Errorf("error.message = %q, must keep the need_user_authorization marker", got) |
| 331 | } |
| 332 | if got, _ := errObj["message"].(string); !strings.Contains(got, "u_golden") { |
| 333 | t.Errorf("error.message = %q, must carry the user open id", got) |
| 334 | } |
| 335 | if got, _ := errObj["hint"].(string); !strings.Contains(got, "auth login") { |
| 336 | t.Errorf("error.hint = %q, must point at auth login", got) |
| 337 | } |
| 338 | if got := errObj["user_open_id"]; got != "u_golden" { |
| 339 | t.Errorf("error.user_open_id = %v, want %q", got, "u_golden") |
| 340 | } |
| 341 | }) |
| 342 | |
| 343 | t.Run("not configured exits 3 with not_configured config envelope", func(t *testing.T) { |
| 344 | f, _, _, _ := cmdutil.TestFactory(t, nil) |
| 345 | errOut := &bytes.Buffer{} |
| 346 | f.IOStreams.ErrOut = errOut |
| 347 | |
| 348 | exit := handleRootError(f, core.NotConfiguredError()) |
| 349 | if exit != int(output.ExitAuth) { |
| 350 | t.Errorf("exit = %d, want %d (config shares ExitAuth)", exit, int(output.ExitAuth)) |
| 351 | } |
| 352 | |
| 353 | errObj := decodeErrorEnvelope(t, errOut.Bytes()) |
| 354 | if got := errObj["type"]; got != "config" { |
| 355 | t.Errorf("error.type = %v, want %q", got, "config") |
| 356 | } |
| 357 | if got := errObj["subtype"]; got != "not_configured" { |
| 358 | t.Errorf("error.subtype = %v, want %q", got, "not_configured") |
| 359 | } |
| 360 | if got, _ := errObj["message"].(string); !strings.Contains(got, "not configured") { |
| 361 | t.Errorf("error.message = %q, want the not-configured message", got) |
| 362 | } |
| 363 | if got, _ := errObj["hint"].(string); !strings.Contains(got, "config init") { |
| 364 | t.Errorf("error.hint = %q, must point at config init", got) |
| 365 | } |
| 366 | }) |
nothing calls this directly
no test coverage detected