111 lines
2.7 KiB
Go
111 lines
2.7 KiB
Go
// Copyright 2026 Alibaba Group
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package app
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseQueryStringToJSON(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name, raw, want string
|
|
}{
|
|
{
|
|
name: "simple key-value",
|
|
raw: "timeMin=2026-04-01&maxResults=10",
|
|
want: `{"maxResults":"10","timeMin":"2026-04-01"}`,
|
|
},
|
|
{
|
|
name: "with special chars",
|
|
raw: "timeMin=2026-04-01T14:00:00+08:00&showDeleted=false",
|
|
want: `{"showDeleted":"false","timeMin":"2026-04-01T14:00:00+08:00"}`,
|
|
},
|
|
{
|
|
name: "empty value skipped",
|
|
raw: "nextToken=&syncToken=abc",
|
|
want: `{"syncToken":"abc"}`,
|
|
},
|
|
{
|
|
name: "all empty",
|
|
raw: "nextToken=&syncToken=",
|
|
want: "{}",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
raw: "",
|
|
want: "{}",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := parseQueryStringToJSON(tt.raw)
|
|
if got != tt.want {
|
|
t.Errorf("parseQueryStringToJSON(%q) = %s, want %s", tt.raw, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRunAPI_QueryStringBlocked(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gf := &GlobalFlags{}
|
|
cmd := newAPICommand(gf)
|
|
|
|
var stdout, stderr bytes.Buffer
|
|
cmd.SetOut(&stdout)
|
|
cmd.SetErr(&stderr)
|
|
|
|
cmd.SetArgs([]string{"GET", "/v1.0/calendar/users/me/events?timeMin=2026-04-01&maxResults=10"})
|
|
err := cmd.Execute()
|
|
|
|
if err == nil {
|
|
t.Fatal("expected error when path contains query string, got nil")
|
|
}
|
|
errMsg := stderr.String()
|
|
if !strings.Contains(errMsg, "--params") {
|
|
t.Errorf("expected --params hint in error, got: %s", errMsg)
|
|
}
|
|
if !strings.Contains(errMsg, "maxResults") {
|
|
t.Errorf("expected parsed query params in error, got: %s", errMsg)
|
|
}
|
|
if !strings.Contains(errMsg, "/v1.0/calendar/users/me/events") {
|
|
t.Errorf("expected clean path in suggestion, got: %s", errMsg)
|
|
}
|
|
}
|
|
|
|
func TestRunAPI_NoErrorWithoutQueryString(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gf := &GlobalFlags{}
|
|
cmd := newAPICommand(gf)
|
|
|
|
var stderr bytes.Buffer
|
|
cmd.SetErr(&stderr)
|
|
cmd.SetOut(&bytes.Buffer{})
|
|
|
|
cmd.SetArgs([]string{"GET", "/v1.0/contact/users/me"})
|
|
err := cmd.Execute()
|
|
|
|
errMsg := stderr.String()
|
|
if strings.Contains(errMsg, "查询参数") {
|
|
t.Errorf("should not reject path without query string, got: %s", errMsg)
|
|
}
|
|
_ = err
|
|
}
|