gitlink-cli/internal/client/client_test.go

760 lines
22 KiB
Go

package client
import (
"encoding/json"
"io"
"mime"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
)
func TestAPIError(t *testing.T) {
err := &APIError{StatusCode: 404, Code: "not_found", Message: "PR not found"}
if err.Error() != "[not_found] PR not found" {
t.Fatalf("Error() = %q, want %q", err.Error(), "[not_found] PR not found")
}
}
func TestSuggestFix(t *testing.T) {
tests := []struct {
code int
want string
}{
{401, "请先运行 gitlink-cli auth login 登录"},
{403, "权限不足,请确认账户权限或联系项目管理员"},
{404, "资源不存在,请检查 owner/repo/id 是否正确"},
{422, "参数校验失败,请检查请求参数"},
{500, ""},
{0, ""},
}
for _, tt := range tests {
t.Run(http.StatusText(tt.code), func(t *testing.T) {
if got := suggestFix(tt.code); got != tt.want {
t.Fatalf("suggestFix(%d) = %q, want %q", tt.code, got, tt.want)
}
})
}
}
func TestClientDoSuccess(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"ok":true,"data":{"key":"value"}}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("GET", "/api/test", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !env.OK {
t.Fatal("expected OK=true")
}
}
func TestClientDoJSONSuffix(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/test.json" {
t.Fatalf("expected path /api/test.json, got %s", r.URL.Path)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Do("GET", "/api/test", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDoJSONSuffixPreserved(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/test.json" {
t.Fatalf("expected path /api/test.json, got %s", r.URL.Path)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Do("GET", "/api/test.json", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDoQueryParams(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("state") != "open" {
t.Fatalf("expected state=open, got %s", r.URL.Query().Get("state"))
}
if r.URL.Query().Get("page") != "1" {
t.Fatalf("expected page=1, got %s", r.URL.Query().Get("page"))
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
q := url.Values{}
q.Set("state", "open")
q.Set("page", "1")
_, err := c.Do("GET", "/api/test", nil, q)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDoHTTPError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("not found"))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Do("GET", "/api/test", nil, nil)
if err == nil {
t.Fatal("expected error for 404")
}
apiErr, ok := err.(*APIError)
if !ok {
t.Fatalf("expected *APIError, got %T", err)
}
if apiErr.StatusCode != 404 {
t.Fatalf("StatusCode = %d, want 404", apiErr.StatusCode)
}
}
func TestClientDoNonJSON(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("plain text response"))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("GET", "/api/test", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !env.OK {
t.Fatal("expected OK=true for non-JSON response")
}
}
func TestClientDoStatusError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status":403,"message":"Forbidden"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("GET", "/api/test", nil, nil)
if err == nil {
t.Fatal("expected error for status=403")
}
if env == nil {
t.Fatal("expected envelope for status error")
}
if env.OK {
t.Fatal("expected OK=false for status error")
}
}
func TestClientDoGatewayCodeError(t *testing.T) {
// Gateway returns {"code":N, "msg":"..."} instead of {"status":N, "message":"..."}
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"code":400,"msg":"Bad Request"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("GET", "/api/test", nil, nil)
if err == nil {
t.Fatal("expected error for code=400")
}
if env == nil {
t.Fatal("expected envelope for code error")
}
if env.OK {
t.Fatal("expected OK=false for code=400")
}
}
func TestClientDoGatewayCode201Success(t *testing.T) {
// Gateway returns code=201 with JSON string data — should be treated as success
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"code":201,"msg":"","data":"{\"title\":\"test\"}"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("POST", "/api/test", map[string]string{"title": "test"}, nil)
if err != nil {
t.Fatalf("unexpected error for code=201: %v", err)
}
if !env.OK {
t.Fatal("expected OK=true for code=201")
}
}
func TestClientDoStatusZero(t *testing.T) {
// status=0, 200, 1 are treated as success
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status":0,"data":"ok"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("GET", "/api/test", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !env.OK {
t.Fatal("expected OK=true for status=0")
}
}
func TestClientDoPaginationMeta(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"total_count":100,"page":1,"limit":20,"data":[]}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("GET", "/api/test", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if env.Meta == nil {
t.Fatal("expected Meta to be populated")
}
if env.Meta.TotalCount != 100 {
t.Fatalf("TotalCount = %d, want 100", env.Meta.TotalCount)
}
if env.Meta.Page != 1 {
t.Fatalf("Page = %d, want 1", env.Meta.Page)
}
if env.Meta.Limit != 20 {
t.Fatalf("Limit = %d, want 20", env.Meta.Limit)
}
}
func TestClientDoPathWithQuery(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// The path query param should be preserved
if r.URL.Query().Get("filepath") != "test.go" {
t.Fatalf("expected filepath=test.go, got %s", r.URL.Query().Get("filepath"))
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Do("GET", "/api/sub_entries?filepath=test.go", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDoPathWithQueryAndExtraParams(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("ref") != "master" {
t.Fatalf("expected ref=master, got %s", r.URL.Query().Get("ref"))
}
if r.URL.Query().Get("filepath") != "test.go" {
t.Fatalf("expected filepath=test.go, got %s", r.URL.Query().Get("filepath"))
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
q := url.Values{}
q.Set("ref", "master")
_, err := c.Do("GET", "/api/sub_entries?filepath=test.go", nil, q)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDoWithBody(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
t.Fatalf("expected POST, got %s", r.Method)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"id":123}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.Do("POST", "/api/create", map[string]string{"title": "test"}, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !env.OK {
t.Fatal("expected OK=true")
}
}
func TestClientPostMultipart(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
t.Fatalf("expected POST, got %s", r.Method)
}
if r.URL.Path != "/api/attachments.json" {
t.Fatalf("expected path /api/attachments.json, got %s", r.URL.Path)
}
mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
t.Fatalf("parse media type: %v", err)
}
if mediaType != "multipart/form-data" {
t.Fatalf("Content-Type = %q, want multipart/form-data", mediaType)
}
if err := r.ParseMultipartForm(1 << 20); err != nil {
t.Fatalf("ParseMultipartForm: %v", err)
}
if got := r.FormValue("description"); got != "release asset" {
t.Fatalf("description = %q, want %q", got, "release asset")
}
files := r.MultipartForm.File["file"]
if len(files) != 1 {
t.Fatalf("expected 1 uploaded file, got %d", len(files))
}
if files[0].Filename != "asset.zip" {
t.Fatalf("filename = %q, want %q", files[0].Filename, "asset.zip")
}
if got := files[0].Header.Get("Content-Type"); got != "application/octet-stream" {
t.Fatalf("part Content-Type = %q, want %q", got, "application/octet-stream")
}
file, err := files[0].Open()
if err != nil {
t.Fatalf("open multipart file: %v", err)
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
t.Fatalf("read multipart file: %v", err)
}
if string(data) != "binary content" {
t.Fatalf("file body = %q, want %q", string(data), "binary content")
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"id":"asset-1"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
env, err := c.PostMultipart("/api/attachments", map[string]string{
"description": "release asset",
}, []MultipartFile{
{
FieldName: "file",
FileName: "asset.zip",
ContentType: "application/octet-stream",
Reader: strings.NewReader("binary content"),
},
})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !env.OK {
t.Fatal("expected OK=true")
}
}
func TestClientPostMultipartRequiresFile(t *testing.T) {
c := &Client{HTTP: &http.Client{}, BaseURL: "https://gitlink.example.com"}
_, err := c.PostMultipart("/attachments", nil, nil)
if err == nil {
t.Fatal("expected error when no multipart file is provided")
}
}
func TestClientGet(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
t.Fatalf("expected GET, got %s", r.Method)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Get("/api/test", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientPost(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
t.Fatalf("expected POST, got %s", r.Method)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Post("/api/test", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientPut(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "PUT" {
t.Fatalf("expected PUT, got %s", r.Method)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Put("/api/test", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDelete(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "DELETE" {
t.Fatalf("expected DELETE, got %s", r.Method)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Delete("/api/test", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDoInvalidURL(t *testing.T) {
c := &Client{HTTP: &http.Client{}, BaseURL: "://invalid"}
_, err := c.Do("GET", "/api/test", nil, nil)
if err == nil {
t.Fatal("expected error for invalid URL")
}
}
func TestClientDebug(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL, Debug: true}
_, err := c.Do("GET", "/api/test", nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestClientDoStatusInt(t *testing.T) {
// Some APIs return status as int, not float64
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status":404,"message":"Not Found"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Do("GET", "/api/test", nil, nil)
if err == nil {
t.Fatal("expected error for status=404 (int)")
}
}
func TestClientNew(t *testing.T) {
dir := t.TempDir()
t.Setenv("GITLINK_CONFIG_DIR", dir)
cfgPath := filepath.Join(dir, "config.yaml")
os.WriteFile(cfgPath, []byte("base_url: https://gitlink.example.com/api/v1\n"), 0644)
cli, err := New()
if err != nil {
t.Fatalf("New error: %v", err)
}
if cli.BaseURL != "https://gitlink.example.com/api/v1" {
t.Fatalf("BaseURL = %q", cli.BaseURL)
}
if cli.HTTP == nil {
t.Fatal("HTTP client is nil")
}
}
func TestPaginateAllSinglePage(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"data":[{"id":1},{"id":2}]}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
items, err := c.PaginateAll("/test", nil)
if err != nil {
t.Fatalf("PaginateAll error: %v", err)
}
if len(items) != 2 {
t.Fatalf("expected 2 items, got %d", len(items))
}
}
func TestPaginateAllMultiPage(t *testing.T) {
callCount := 0
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
callCount++
w.Header().Set("Content-Type", "application/json")
page := r.URL.Query().Get("page")
if page == "1" {
w.Write([]byte(`{"data":[{"id":1},{"id":2}]}`))
} else {
w.Write([]byte(`{"data":[{"id":3}]}`))
}
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
params := url.Values{}
params.Set("limit", "2")
items, err := c.PaginateAll("/test", params)
if err != nil {
t.Fatalf("PaginateAll error: %v", err)
}
if len(items) != 3 {
t.Fatalf("expected 3 items, got %d", len(items))
}
if callCount != 2 {
t.Fatalf("expected 2 API calls, got %d", callCount)
}
}
func TestPaginateAllWrappedData(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"data":[{"id":1},{"id":2}],"total_count":2}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
items, err := c.PaginateAll("/test", nil)
if err != nil {
t.Fatalf("PaginateAll error: %v", err)
}
if len(items) != 2 {
t.Fatalf("expected 2 items, got %d", len(items))
}
}
func TestPaginateAllSingleObject(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"name":"single-object"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
items, err := c.PaginateAll("/test", nil)
if err != nil {
t.Fatalf("PaginateAll error: %v", err)
}
if len(items) != 1 {
t.Fatalf("expected 1 item, got %d", len(items))
}
var data map[string]interface{}
json.Unmarshal(items[0], &data)
if data["name"] != "single-object" {
t.Fatalf("unexpected data: %v", data)
}
}
func TestPaginateAllHTTPError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.PaginateAll("/test", nil)
if err == nil {
t.Fatal("expected error for 500 response")
}
}
func TestPaginateAllNotOK(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status":500,"message":"error"}`))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.PaginateAll("/test", nil)
if err == nil {
t.Fatal("expected error when envelope ok=false")
}
}
func TestClientDownload(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/attachments/7" {
t.Fatalf("unexpected path: %s", r.URL.Path)
}
w.Header().Set("Content-Type", "application/octet-stream")
w.Write([]byte("asset bytes"))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL + "/api"}
result, err := c.Download("/api/attachments/7")
if err != nil {
t.Fatalf("Download error: %v", err)
}
if string(result.Data) != "asset bytes" {
t.Fatalf("data = %q", result.Data)
}
if result.ContentType != "application/octet-stream" {
t.Fatalf("content type = %q", result.ContentType)
}
}
func TestClientDownloadAPIPathWithV1BaseURL(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/attachments/7" {
t.Fatalf("unexpected path: %s", r.URL.Path)
}
w.Write([]byte("asset bytes"))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL + "/api/v1"}
result, err := c.Download("/api/attachments/7")
if err != nil {
t.Fatalf("Download error: %v", err)
}
if string(result.Data) != "asset bytes" {
t.Fatalf("data = %q", result.Data)
}
}
func TestClientDownloadAbsoluteURL(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/files/release.zip" {
t.Fatalf("unexpected path: %s", r.URL.Path)
}
w.Write([]byte("zip bytes"))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: "https://gitlink.example.com/api"}
result, err := c.Download(server.URL + "/files/release.zip")
if err != nil {
t.Fatalf("Download error: %v", err)
}
if string(result.Data) != "zip bytes" {
t.Fatalf("data = %q", result.Data)
}
}
func TestClientDownloadWebRelativeURL(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/owner/repo/releases/download/v1/app.zip" {
t.Fatalf("unexpected path: %s", r.URL.Path)
}
w.Write([]byte("asset bytes"))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL + "/api"}
result, err := c.Download("/owner/repo/releases/download/v1/app.zip")
if err != nil {
t.Fatalf("Download error: %v", err)
}
if string(result.Data) != "asset bytes" {
t.Fatalf("data = %q", result.Data)
}
}
func TestClientDownloadHTTPError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("missing"))
}))
defer server.Close()
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
_, err := c.Download("/missing")
if err == nil {
t.Fatal("expected download error")
}
}
func TestShouldAppendJSONSuffixSkipsRawFilePath(t *testing.T) {
if shouldAppendJSONSuffix("/Gitlink/forgeplus/raw/master/README.md") {
t.Fatal("raw file path should not get .json suffix")
}
}
func TestShouldAppendJSONSuffixKeepsRawRepositoryName(t *testing.T) {
if !shouldAppendJSONSuffix("/users/raw/projects") {
t.Fatal("regular API path should get .json suffix")
}
}
func TestShouldAppendJSONSuffixSkipsExistingJSONPath(t *testing.T) {
if shouldAppendJSONSuffix("/projects.json") {
t.Fatal("existing .json path should not get another suffix")
}
}
func TestShouldAppendJSONSuffixSkipsWikiOpenPaths(t *testing.T) {
paths := []string{
"/wiki/open/createWiki",
"/wiki/open/getWiki",
"/wiki/open/updateWiki",
"/wiki/open/deleteWiki",
"/wiki/open/wikiPages",
}
for _, p := range paths {
if shouldAppendJSONSuffix(p) {
t.Errorf("wiki/open path %q should not get .json suffix", p)
}
}
}