carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package main
2
3import (
4 "bytes"
5 "strings"
6 "testing"
7)
8
9func TestSeveralAccountsErr(t *testing.T) {
10 err := severalAccountsErr([]apiAccountEntry{
11 {Name: "tom@keymail.dev", Sqid: "bdk"}, {Name: "acme", Sqid: "bce"}})
12 want := "you belong to several accounts — say which with --account: tom@keymail.dev (bdk), acme (bce)"
13 if err.Error() != want {
14 t.Fatalf("severalAccountsErr = %q\nwant %q", err, want)
15 }
16}
17
18func TestChooseAccount(t *testing.T) {
19 accts := []apiAccountEntry{
20 {Name: "tom@keymail.dev", Sqid: "bdk"}, {Name: "acme", Sqid: "bce"}}
21 refusal := severalAccountsErr(accts).Error()
22
23 // A clean pick of the second entry, declining the save.
24 var out bytes.Buffer
25 picked, save, err := chooseAccount(strings.NewReader("2\nn\n"), &out, "https://console.example", accts, ".carlos/config")
26 if err != nil || picked.Sqid != "bce" || save {
27 t.Fatalf("pick 2 = %+v save=%v err=%v", picked, save, err)
28 }
29 for _, want := range []string{
30 "you belong to several accounts on https://console.example",
31 "1. tom@keymail.dev (bdk)", "2. acme (bce)", "account [1-2]:",
32 "save acme as this directory's default account (.carlos/config)? [y/N]",
33 } {
34 if !strings.Contains(out.String(), want) {
35 t.Fatalf("chooser output missing %q:\n%s", want, out.String())
36 }
37 }
38
39 // Saying y to the save prompt.
40 out.Reset()
41 picked, save, err = chooseAccount(strings.NewReader("1\ny\n"), &out, "https://console.example", accts, ".carlos/config")
42 if err != nil || picked.Sqid != "bdk" || !save {
43 t.Fatalf("pick 1 + save = %+v save=%v err=%v", picked, save, err)
44 }
45
46 // An empty saveDest — the caller decided saving is off the table (from
47 // $HOME the "project" file would be the global config) — asks nothing
48 // and never saves, even with a y queued up.
49 out.Reset()
50 picked, save, err = chooseAccount(strings.NewReader("1\ny\n"), &out, "https://console.example", accts, "")
51 if err != nil || picked.Sqid != "bdk" || save {
52 t.Fatalf("no-dest pick = %+v save=%v err=%v, want pick without a save", picked, save, err)
53 }
54 if strings.Contains(out.String(), "save ") {
55 t.Fatalf("no-dest chooser must not offer the save:\n%s", out.String())
56 }
57
58 // An empty save answer means no — N is the default.
59 out.Reset()
60 _, save, err = chooseAccount(strings.NewReader("1\n\n"), &out, "https://console.example", accts, ".carlos/config")
61 if err != nil || save {
62 t.Fatalf("empty save answer = save=%v err=%v, want no-save", save, err)
63 }
64
65 // EOF at the save prompt also means no; the pick itself stands.
66 out.Reset()
67 picked, save, err = chooseAccount(strings.NewReader("1\n"), &out, "https://console.example", accts, ".carlos/config")
68 if err != nil || picked.Sqid != "bdk" || save {
69 t.Fatalf("EOF at save = %+v save=%v err=%v", picked, save, err)
70 }
71
72 // Junk once re-prompts; a valid second answer lands.
73 out.Reset()
74 picked, _, err = chooseAccount(strings.NewReader("zzz\n1\nn\n"), &out, "https://console.example", accts, ".carlos/config")
75 if err != nil || picked.Sqid != "bdk" {
76 t.Fatalf("junk-then-1 = %+v err=%v", picked, err)
77 }
78 if strings.Count(out.String(), "account [1-2]:") != 2 {
79 t.Fatalf("want exactly one re-prompt:\n%s", out.String())
80 }
81
82 // Junk twice — including out-of-range numbers — is the refusal.
83 for _, input := range []string{"zzz\nzzz\n", "0\n3\n", ""} {
84 out.Reset()
85 if _, _, err = chooseAccount(strings.NewReader(input), &out, "https://console.example", accts, ".carlos/config"); err == nil || err.Error() != refusal {
86 t.Fatalf("input %q = %v, want the several-accounts refusal", input, err)
87 }
88 }
89}
90