bf9395e022
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / results (push) Has been cancelled
CI / deadcode (push) Has been cancelled
CI / e2e-live (push) Has been cancelled
121 lines
3.5 KiB
Go
121 lines
3.5 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package platform_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/larksuite/cli/extension/platform"
|
|
)
|
|
|
|
func TestRisk_Rank_orderedTaxonomy(t *testing.T) {
|
|
cases := []struct {
|
|
level platform.Risk
|
|
want int
|
|
}{
|
|
{platform.RiskRead, 0},
|
|
{platform.RiskWrite, 1},
|
|
{platform.RiskHighRiskWrite, 2},
|
|
}
|
|
for _, c := range cases {
|
|
got, ok := c.level.Rank()
|
|
if !ok || got != c.want {
|
|
t.Errorf("Risk(%q).Rank() = (%d,%v), want (%d,true)", c.level, got, ok, c.want)
|
|
}
|
|
}
|
|
|
|
if _, ok := platform.Risk("unknown-level").Rank(); ok {
|
|
t.Fatalf("unknown-level.Rank() ok should be false")
|
|
}
|
|
if _, ok := platform.Risk("").Rank(); ok {
|
|
t.Fatalf("empty.Rank() ok should be false (signals 'no risk annotation')")
|
|
}
|
|
}
|
|
|
|
// The Risk ordering must be strict: read < write < high-risk-write. The
|
|
// policy engine compares ranks; a regression that swaps the order would
|
|
// silently let high-risk commands pass under MaxRisk=write.
|
|
func TestRisk_Rank_strictlyMonotonic(t *testing.T) {
|
|
r1, _ := platform.RiskRead.Rank()
|
|
r2, _ := platform.RiskWrite.Rank()
|
|
r3, _ := platform.RiskHighRiskWrite.Rank()
|
|
if !(r1 < r2 && r2 < r3) {
|
|
t.Fatalf("Risk ranks not monotonic: read=%d write=%d high=%d", r1, r2, r3)
|
|
}
|
|
}
|
|
|
|
func TestRisk_IsValid(t *testing.T) {
|
|
valid := []platform.Risk{platform.RiskRead, platform.RiskWrite, platform.RiskHighRiskWrite}
|
|
for _, r := range valid {
|
|
if !r.IsValid() {
|
|
t.Errorf("%q.IsValid() = false, want true", r)
|
|
}
|
|
}
|
|
invalid := []platform.Risk{"", "wrtie", "Read", "READ", " read "}
|
|
for _, r := range invalid {
|
|
if r.IsValid() {
|
|
t.Errorf("%q.IsValid() = true, want false", r)
|
|
}
|
|
}
|
|
}
|
|
|
|
// ParseRisk distinguishes absent (empty input) from invalid (typo).
|
|
// The absent / invalid split mirrors the cmdpolicy engine's
|
|
// risk_not_annotated vs risk_invalid reason codes.
|
|
func TestParseRisk(t *testing.T) {
|
|
// Empty -> ("", nil) — "not specified"
|
|
got, err := platform.ParseRisk("")
|
|
if err != nil || got != "" {
|
|
t.Errorf(`ParseRisk("") = (%q,%v), want ("",nil)`, got, err)
|
|
}
|
|
|
|
// Valid values pass through
|
|
for _, want := range []platform.Risk{platform.RiskRead, platform.RiskWrite, platform.RiskHighRiskWrite} {
|
|
got, err := platform.ParseRisk(string(want))
|
|
if err != nil || got != want {
|
|
t.Errorf("ParseRisk(%q) = (%q,%v), want (%q,nil)", want, got, err, want)
|
|
}
|
|
}
|
|
|
|
// Typo -> error, strict matching (case-sensitive, no trim)
|
|
bad := []string{"wrtie", "Read", "READ", " read ", "high_risk_write"}
|
|
for _, s := range bad {
|
|
got, err := platform.ParseRisk(s)
|
|
if err == nil {
|
|
t.Errorf("ParseRisk(%q) succeeded (got %q), want error", s, got)
|
|
}
|
|
if got != "" {
|
|
t.Errorf("ParseRisk(%q) returned %q, want empty Risk on error", s, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseIdentity(t *testing.T) {
|
|
got, err := platform.ParseIdentity("")
|
|
if err != nil || got != "" {
|
|
t.Errorf(`ParseIdentity("") = (%q,%v), want ("",nil)`, got, err)
|
|
}
|
|
for _, want := range []platform.Identity{platform.IdentityUser, platform.IdentityBot} {
|
|
got, err := platform.ParseIdentity(string(want))
|
|
if err != nil || got != want {
|
|
t.Errorf("ParseIdentity(%q) = (%q,%v)", want, got, err)
|
|
}
|
|
}
|
|
if _, err := platform.ParseIdentity("admin"); err == nil {
|
|
t.Fatalf(`ParseIdentity("admin") want error`)
|
|
}
|
|
}
|
|
|
|
func TestIdentity_IsValid(t *testing.T) {
|
|
if !platform.IdentityUser.IsValid() {
|
|
t.Error("user.IsValid() = false")
|
|
}
|
|
if !platform.IdentityBot.IsValid() {
|
|
t.Error("bot.IsValid() = false")
|
|
}
|
|
if platform.Identity("admin").IsValid() {
|
|
t.Error("admin.IsValid() = true")
|
|
}
|
|
}
|