mirror of
https://github.com/larksuite/cli.git
synced 2026-07-07 00:55:53 +08:00
135 lines
4.5 KiB
Go
135 lines
4.5 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package rules
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/larksuite/cli/internal/qualitygate/manifest"
|
|
"github.com/larksuite/cli/internal/qualitygate/report"
|
|
)
|
|
|
|
func TestCheckDefaultOutputWarnsListWithoutLimit(t *testing.T) {
|
|
m := manifest.Manifest{Commands: []manifest.Command{{
|
|
Path: "im messages list",
|
|
Runnable: true,
|
|
}}}
|
|
diags, facts := CheckDefaultOutput(m)
|
|
if len(diags) == 0 || diags[0].Rule != "default_output" || diags[0].Action != report.ActionWarning {
|
|
t.Fatalf("got diagnostics %#v", diags)
|
|
}
|
|
if diags[0].CommandPath != "im messages list" || diags[0].SubjectType != "output" {
|
|
t.Fatalf("default output diagnostic subject = %#v", diags[0])
|
|
}
|
|
if len(facts) != 1 || !facts[0].IsList || facts[0].HasDefaultLimit {
|
|
t.Fatalf("got facts %#v", facts)
|
|
}
|
|
}
|
|
|
|
func TestCheckDefaultOutputDoesNotEmitEstimatedByteFacts(t *testing.T) {
|
|
m := manifest.Manifest{Commands: []manifest.Command{{
|
|
Path: "im messages list",
|
|
Runnable: true,
|
|
}}}
|
|
diags, facts := CheckDefaultOutput(m)
|
|
for _, diag := range diags {
|
|
if diag.Rule == "default_output_budget" {
|
|
t.Fatalf("default_output_budget must not rely on estimated bytes: %#v", diags)
|
|
}
|
|
}
|
|
data, err := json.Marshal(facts[0])
|
|
if err != nil {
|
|
t.Fatalf("marshal output fact: %v", err)
|
|
}
|
|
if strings.Contains(string(data), "default_bytes") || strings.Contains(string(data), "sample_bytes") {
|
|
t.Fatalf("output fact must not carry estimated byte fields: %s", data)
|
|
}
|
|
}
|
|
|
|
func TestCheckDefaultOutputDoesNotSpecialCaseGeneratedServiceListWithoutFields(t *testing.T) {
|
|
m := manifest.Manifest{Commands: []manifest.Command{{
|
|
Path: "mail messages list",
|
|
Runnable: true,
|
|
Source: manifest.SourceService,
|
|
Generated: true,
|
|
Flags: []manifest.Flag{{Name: "page-limit", DefValue: "10"}},
|
|
}}}
|
|
diags, _ := CheckDefaultOutput(m)
|
|
if len(diags) != 0 {
|
|
t.Fatalf("generated service commands are excluded from v1 manifest and should not have a special output reject, got %#v", diags)
|
|
}
|
|
}
|
|
|
|
func TestCheckDefaultOutputAcceptsDefaultLimit(t *testing.T) {
|
|
m := manifest.Manifest{Commands: []manifest.Command{{
|
|
Path: "im messages list",
|
|
Runnable: true,
|
|
Flags: []manifest.Flag{{Name: "page-size", DefValue: "20"}},
|
|
}}}
|
|
diags, facts := CheckDefaultOutput(m)
|
|
if len(diags) != 0 {
|
|
t.Fatalf("got diagnostics %#v", diags)
|
|
}
|
|
if len(facts) != 1 || !facts[0].HasDefaultLimit {
|
|
t.Fatalf("got facts %#v", facts)
|
|
}
|
|
}
|
|
|
|
func TestCheckDefaultOutputDoesNotTreatZeroDefaultAsLimit(t *testing.T) {
|
|
m := manifest.Manifest{Commands: []manifest.Command{{
|
|
Path: "im messages list",
|
|
Runnable: true,
|
|
Flags: []manifest.Flag{{Name: "page-limit", DefValue: "0"}},
|
|
}}}
|
|
diags, facts := CheckDefaultOutput(m)
|
|
if len(diags) == 0 || diags[0].Rule != "default_output" {
|
|
t.Fatalf("expected missing default limit warning, got %#v", diags)
|
|
}
|
|
if len(facts) != 1 || facts[0].HasDefaultLimit {
|
|
t.Fatalf("page-limit=0 should not count as bounded default limit: %#v", facts)
|
|
}
|
|
}
|
|
|
|
func TestDefaultOutputRejectsListWithoutLimitOrDecisionFields(t *testing.T) {
|
|
m := manifest.Manifest{Commands: []manifest.Command{{
|
|
Path: "im messages list",
|
|
Runnable: true,
|
|
Flags: []manifest.Flag{{Name: "fields"}},
|
|
DefaultFields: []string{"raw_payload"},
|
|
}}}
|
|
diags, facts := CheckDefaultOutput(m)
|
|
if len(diags) == 0 || diags[0].Action != report.ActionReject || diags[0].Rule != "default_output_contract" {
|
|
t.Fatalf("expected default output reject, got %#v", diags)
|
|
}
|
|
if diags[0].CommandPath != "im messages list" || diags[0].SubjectType != "output" {
|
|
t.Fatalf("default output contract diagnostic subject = %#v", diags[0])
|
|
}
|
|
if facts[0].HasDecisionField {
|
|
t.Fatalf("raw_payload should not satisfy decision field family")
|
|
}
|
|
}
|
|
|
|
func TestCheckDefaultOutputDoesNotTreatSubstringsAsDecisionFields(t *testing.T) {
|
|
m := manifest.Manifest{Commands: []manifest.Command{{
|
|
Path: "drive files list",
|
|
Runnable: true,
|
|
Flags: []manifest.Flag{{Name: "page-size", DefValue: "20"}},
|
|
DefaultFields: []string{
|
|
"width",
|
|
"filename",
|
|
"runtime",
|
|
"curl",
|
|
},
|
|
}}}
|
|
diags, facts := CheckDefaultOutput(m)
|
|
if len(diags) != 1 || diags[0].Action != report.ActionReject || diags[0].Rule != "default_output_contract" {
|
|
t.Fatalf("substring-only decision fields should reject, got %#v", diags)
|
|
}
|
|
if len(facts) != 1 || facts[0].HasDecisionField {
|
|
t.Fatalf("substring-only fields should not satisfy decision field family: %#v", facts)
|
|
}
|
|
}
|