| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "fmt" |
| 6 | "io" |
| 7 | "net/http" |
| 8 | "net/http/httptest" |
| 9 | "testing" |
| 10 | ) |
| 11 | |
| 12 | // Review Focus 5: the spec's order, flags first with the app after, and |
| 13 | // --app all name one app; two names do not. |
| 14 | func TestAppsSetApp(t *testing.T) { |
| 15 | for _, tc := range []struct { |
| 16 | lead, flagApp string |
| 17 | rest []string |
| 18 | want, err string |
| 19 | }{ |
| 20 | {lead: "shop", want: "shop"}, |
| 21 | {flagApp: "shop", want: "shop"}, |
| 22 | {rest: []string{"shop"}, want: "shop"}, |
| 23 | {lead: "shop", flagApp: "other", err: appsSetTwoApps}, |
| 24 | {lead: "shop", rest: []string{"other"}, err: appsSetTwoApps}, |
| 25 | {flagApp: "shop", rest: []string{"other"}, err: appsSetTwoApps}, |
| 26 | {err: appsSetUsage}, |
| 27 | } { |
| 28 | got, err := appsSetApp(tc.lead, tc.flagApp, tc.rest) |
| 29 | if tc.err != "" { |
| 30 | if err == nil || err.Error() != tc.err { |
| 31 | t.Errorf("appsSetApp(%q, %q, %q) = %q, %v; want error %q", tc.lead, tc.flagApp, tc.rest, got, err, tc.err) |
| 32 | } |
| 33 | continue |
| 34 | } |
| 35 | if err != nil || got != tc.want { |
| 36 | t.Errorf("appsSetApp(%q, %q, %q) = %q, %v; want %q", tc.lead, tc.flagApp, tc.rest, got, err, tc.want) |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | func TestLeadingArg(t *testing.T) { |
| 42 | if w, rest := leadingArg([]string{"shop", "--swap", "hold"}); w != "shop" || len(rest) != 2 { |
| 43 | t.Errorf("leadingArg = %q, %q", w, rest) |
| 44 | } |
| 45 | if w, rest := leadingArg([]string{"--swap", "hold", "shop"}); w != "" || len(rest) != 3 { |
| 46 | t.Errorf("a flag first leaves everything to the flag parser: %q, %q", w, rest) |
| 47 | } |
| 48 | if w, rest := leadingArg(nil); w != "" || rest != nil { |
| 49 | t.Errorf("leadingArg(nil) = %q, %q", w, rest) |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | func TestAppsSetRequest(t *testing.T) { |
| 54 | if _, err := appsSetRequest("", 0, false, false); err == nil || err.Error() != appsSetNothing { |
| 55 | t.Errorf("no flags: %v", err) |
| 56 | } |
| 57 | if _, err := appsSetRequest("fast", 0, true, false); err == nil || err.Error() != fmt.Sprintf(appsSetBadSwap, "fast") { |
| 58 | t.Errorf("--swap fast: %v", err) |
| 59 | } |
| 60 | if _, err := appsSetRequest("", 0, false, true); err == nil || err.Error() != appsSetBadConcurrency { |
| 61 | t.Errorf("--swap-concurrency 0: %v", err) |
| 62 | } |
| 63 | req, err := appsSetRequest(" hold ", 3, true, true) |
| 64 | if err != nil || req.Swap == nil || *req.Swap != "hold" || req.SwapConcurrency == nil || *req.SwapConcurrency != 3 { |
| 65 | t.Errorf("hold/3: %+v, %v", req, err) |
| 66 | } |
| 67 | if req, err = appsSetRequest("", 2, false, true); err != nil || req.Swap != nil || *req.SwapConcurrency != 2 { |
| 68 | t.Errorf("concurrency only: %+v, %v", req, err) |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | func TestAppsSetStuck(t *testing.T) { |
| 73 | hold, two := "hold", 2 |
| 74 | if err := appsSetStuck(swapPolicyReq{Swap: &hold, SwapConcurrency: &two}, apiSwapPolicy{Swap: "hold", Concurrency: 2}); err != nil { |
| 75 | t.Errorf("a matching echo: %v", err) |
| 76 | } |
| 77 | if err := appsSetStuck(swapPolicyReq{Swap: &hold}, apiSwapPolicy{Swap: "overlap", Concurrency: 1}); err == nil { |
| 78 | t.Error("an echo of overlap for a hold request passed") |
| 79 | } |
| 80 | if err := appsSetStuck(swapPolicyReq{SwapConcurrency: &two}, apiSwapPolicy{Swap: "overlap", Concurrency: 2}); err != nil { |
| 81 | t.Errorf("the unnamed half may be anything: %v", err) |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | func TestAPISessionSetSwapPolicyWireShape(t *testing.T) { |
| 86 | var method, path, body string |
| 87 | ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 88 | b, _ := io.ReadAll(r.Body) |
| 89 | method, path, body = r.Method, r.URL.Path, string(b) |
| 90 | w.Header().Set("Content-Type", "application/json") |
| 91 | io.WriteString(w, `{"swap":"hold","swap_concurrency":1}`) |
| 92 | })) |
| 93 | defer ts.Close() |
| 94 | hold := "hold" |
| 95 | got, err := newTestSession(ts.URL).setSwapPolicy(context.Background(), apiAcct{Seg: "bab"}, "shop", swapPolicyReq{Swap: &hold}) |
| 96 | if err != nil || got != (apiSwapPolicy{Swap: "hold", Concurrency: 1}) { |
| 97 | t.Fatalf("setSwapPolicy = %+v, %v", got, err) |
| 98 | } |
| 99 | if method != http.MethodPut || path != "/api/cli/apps/bab/shop/swap" || body != `{"swap":"hold"}` { |
| 100 | t.Fatalf("sent %s %s %s", method, path, body) |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | func TestAPISessionSetSwapPolicyOldConsole(t *testing.T) { |
| 105 | ts := httptest.NewServer(http.NotFoundHandler()) |
| 106 | defer ts.Close() |
| 107 | hold := "hold" |
| 108 | _, err := newTestSession(ts.URL).setSwapPolicy(context.Background(), apiAcct{Seg: "bab"}, "shop", swapPolicyReq{Swap: &hold}) |
| 109 | if err == nil || err.Error() != fmt.Sprintf(appsSetOldConsole, "shop") { |
| 110 | t.Fatalf("err = %v", err) |
| 111 | } |
| 112 | } |
| 113 | |