package policy import ( "strings" "testing" "time" ) func TestNoBlockGivesDefaults(t *testing.T) { // Ejemplos sueltos en el texto NO deben conceder permisos. md := "# Agente\n\nEjemplo: EXECUTION_MODE=unrestricted\n\n```text\nALLOW_DELETE=true\n```\n" p, err := Parse(md) if err != nil { t.Fatalf("Parse: %v", err) } if p.Declared { t.Error("Declared should be false") } if p.Mode != ModeGuarded { t.Errorf("Mode = %s, want guarded", p.Mode) } for _, c := range AllCapabilities { if p.Allows(c) { t.Errorf("%s must default to false", c) } } if !p.BackupBeforeSystemEdit { t.Error("BACKUP_BEFORE_SYSTEM_EDIT must default to true") } if p.DefaultCommandTimeout != 60*time.Second { t.Errorf("timeout = %v", p.DefaultCommandTimeout) } } func TestPolicyBlock(t *testing.T) { md := strings.Join([]string{ "# Identidad", "", "```policy", "# comentario", "EXECUTION_MODE=privileged", "ALLOW_NETWORK=true", "ALLOW_DELETE=false", "BACKUP_BEFORE_SYSTEM_EDIT=false", "DEFAULT_COMMAND_TIMEOUT=120", "TASK_ORDER=02-b.md, 01-a.md", "SOMETHING_NEW=1", "```", "", }, "\n") p, err := Parse(md) if err != nil { t.Fatalf("Parse: %v", err) } if !p.Declared || p.Mode != ModePrivileged { t.Fatalf("Declared=%v Mode=%s", p.Declared, p.Mode) } if !p.Allows(CapNetwork) || p.Allows(CapDelete) { t.Error("capabilities not applied correctly") } if p.Allows(CapReboot) { t.Error("undeclared ALLOW_REBOOT must be false") } if p.BackupBeforeSystemEdit { t.Error("backup should be false") } if p.DefaultCommandTimeout != 120*time.Second { t.Errorf("timeout = %v", p.DefaultCommandTimeout) } if strings.Join(p.TaskOrder, "|") != "02-b.md|01-a.md" { t.Errorf("TaskOrder = %v", p.TaskOrder) } if len(p.Unknown) != 1 || p.Unknown[0] != "SOMETHING_NEW" { t.Errorf("Unknown = %v", p.Unknown) } } func TestUnrestrictedOnlyWhenExplicit(t *testing.T) { p, err := Parse("```policy\nEXECUTION_MODE=unrestricted\n```\n") if err != nil { t.Fatal(err) } if p.Mode != ModeUnrestricted { t.Errorf("Mode = %s", p.Mode) } // Incluso unrestricted no concede capacidades no declaradas. if p.Allows(CapReboot) { t.Error("unrestricted must not imply ALLOW_REBOOT") } } func TestPolicyInsideOtherFenceIsIgnored(t *testing.T) { // Un "```policy" dentro de un bloque ```` (4 backticks) es solo texto. md := "````markdown\n```policy\nEXECUTION_MODE=unrestricted\n```\n````\n" p, err := Parse(md) if err != nil { t.Fatal(err) } if p.Declared || p.Mode != ModeGuarded { t.Errorf("nested example must be ignored: Declared=%v Mode=%s", p.Declared, p.Mode) } } func TestParseErrors(t *testing.T) { cases := map[string]string{ "two blocks": "```policy\nALLOW_NETWORK=true\n```\n```policy\nALLOW_DELETE=true\n```\n", "bad mode": "```policy\nEXECUTION_MODE=god\n```\n", "bad bool": "```policy\nALLOW_DELETE=maybe\n```\n", "duplicate": "```policy\nALLOW_DELETE=false\nALLOW_DELETE=true\n```\n", "no equals": "```policy\nALLOW_DELETE\n```\n", "bad timeout": "```policy\nDEFAULT_COMMAND_TIMEOUT=0\n```\n", "unterminated": "```policy\nALLOW_DELETE=true\n", } for name, md := range cases { if _, err := Parse(md); err == nil { t.Errorf("%s: expected error", name) } } } func TestMaxSteps(t *testing.T) { p, _ := Parse("") if p.MaxSteps != 40 { t.Errorf("default MaxSteps = %d", p.MaxSteps) } p, err := Parse("```policy\nMAX_STEPS=12\n```\n") if err != nil || p.MaxSteps != 12 { t.Fatalf("%v %v", p, err) } if _, err := Parse("```policy\nMAX_STEPS=0\n```\n"); err == nil { t.Error("MAX_STEPS=0 must fail") } } func TestMaxDownloadSize(t *testing.T) { p, _ := Parse("") if p.MaxDownloadSize != 1<<30 { t.Errorf("default = %d", p.MaxDownloadSize) } for in, want := range map[string]int64{"1048576": 1 << 20, "512M": 512 << 20, "2G": 2 << 30, "10KB": 10 << 10} { p, err := Parse("```policy\nMAX_DOWNLOAD_SIZE=" + in + "\n```\n") if err != nil || p.MaxDownloadSize != want { t.Errorf("%s: %d %v", in, p.MaxDownloadSize, err) } } if _, err := Parse("```policy\nMAX_DOWNLOAD_SIZE=lots\n```\n"); err == nil { t.Error("invalid size must fail") } }