package main import ( "context" "fmt" "io" "net/http" "net/http/httptest" "testing" ) // Review Focus 5: the spec's order, flags first with the app after, and // --app all name one app; two names do not. func TestAppsSetApp(t *testing.T) { for _, tc := range []struct { lead, flagApp string rest []string want, err string }{ {lead: "shop", want: "shop"}, {flagApp: "shop", want: "shop"}, {rest: []string{"shop"}, want: "shop"}, {lead: "shop", flagApp: "other", err: appsSetTwoApps}, {lead: "shop", rest: []string{"other"}, err: appsSetTwoApps}, {flagApp: "shop", rest: []string{"other"}, err: appsSetTwoApps}, {err: appsSetUsage}, } { got, err := appsSetApp(tc.lead, tc.flagApp, tc.rest) if tc.err != "" { if err == nil || err.Error() != tc.err { t.Errorf("appsSetApp(%q, %q, %q) = %q, %v; want error %q", tc.lead, tc.flagApp, tc.rest, got, err, tc.err) } continue } if err != nil || got != tc.want { t.Errorf("appsSetApp(%q, %q, %q) = %q, %v; want %q", tc.lead, tc.flagApp, tc.rest, got, err, tc.want) } } } func TestLeadingArg(t *testing.T) { if w, rest := leadingArg([]string{"shop", "--swap", "hold"}); w != "shop" || len(rest) != 2 { t.Errorf("leadingArg = %q, %q", w, rest) } if w, rest := leadingArg([]string{"--swap", "hold", "shop"}); w != "" || len(rest) != 3 { t.Errorf("a flag first leaves everything to the flag parser: %q, %q", w, rest) } if w, rest := leadingArg(nil); w != "" || rest != nil { t.Errorf("leadingArg(nil) = %q, %q", w, rest) } } func TestAppsSetRequest(t *testing.T) { if _, err := appsSetRequest("", 0, false, false); err == nil || err.Error() != appsSetNothing { t.Errorf("no flags: %v", err) } if _, err := appsSetRequest("fast", 0, true, false); err == nil || err.Error() != fmt.Sprintf(appsSetBadSwap, "fast") { t.Errorf("--swap fast: %v", err) } if _, err := appsSetRequest("", 0, false, true); err == nil || err.Error() != appsSetBadConcurrency { t.Errorf("--swap-concurrency 0: %v", err) } req, err := appsSetRequest(" hold ", 3, true, true) if err != nil || req.Swap == nil || *req.Swap != "hold" || req.SwapConcurrency == nil || *req.SwapConcurrency != 3 { t.Errorf("hold/3: %+v, %v", req, err) } if req, err = appsSetRequest("", 2, false, true); err != nil || req.Swap != nil || *req.SwapConcurrency != 2 { t.Errorf("concurrency only: %+v, %v", req, err) } } func TestAppsSetStuck(t *testing.T) { hold, two := "hold", 2 if err := appsSetStuck(swapPolicyReq{Swap: &hold, SwapConcurrency: &two}, apiSwapPolicy{Swap: "hold", Concurrency: 2}); err != nil { t.Errorf("a matching echo: %v", err) } if err := appsSetStuck(swapPolicyReq{Swap: &hold}, apiSwapPolicy{Swap: "overlap", Concurrency: 1}); err == nil { t.Error("an echo of overlap for a hold request passed") } if err := appsSetStuck(swapPolicyReq{SwapConcurrency: &two}, apiSwapPolicy{Swap: "overlap", Concurrency: 2}); err != nil { t.Errorf("the unnamed half may be anything: %v", err) } } func TestAPISessionSetSwapPolicyWireShape(t *testing.T) { var method, path, body string ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { b, _ := io.ReadAll(r.Body) method, path, body = r.Method, r.URL.Path, string(b) w.Header().Set("Content-Type", "application/json") io.WriteString(w, `{"swap":"hold","swap_concurrency":1}`) })) defer ts.Close() hold := "hold" got, err := newTestSession(ts.URL).setSwapPolicy(context.Background(), apiAcct{Seg: "bab"}, "shop", swapPolicyReq{Swap: &hold}) if err != nil || got != (apiSwapPolicy{Swap: "hold", Concurrency: 1}) { t.Fatalf("setSwapPolicy = %+v, %v", got, err) } if method != http.MethodPut || path != "/api/cli/apps/bab/shop/swap" || body != `{"swap":"hold"}` { t.Fatalf("sent %s %s %s", method, path, body) } } func TestAPISessionSetSwapPolicyOldConsole(t *testing.T) { ts := httptest.NewServer(http.NotFoundHandler()) defer ts.Close() hold := "hold" _, err := newTestSession(ts.URL).setSwapPolicy(context.Background(), apiAcct{Seg: "bab"}, "shop", swapPolicyReq{Swap: &hold}) if err == nil || err.Error() != fmt.Sprintf(appsSetOldConsole, "shop") { t.Fatalf("err = %v", err) } }