package main import ( "regexp" "strings" "testing" "housecarl/internal/matrix" "housecarl/internal/model" ) func TestDurations(t *testing.T) { for in, want := range map[string]int{"3600": 3600, "12h": 43200, "30m": 1800, "1d": 86400, "1d12h": 129600, "1h30m": 5400} { if got, err := parseSeconds(in); err != nil || got != want { t.Errorf("parseSeconds(%q) = %d, %v; want %d", in, got, err, want) } } for _, bad := range []string{"12x", "d", "1d2x"} { if _, err := parseSeconds(bad); err == nil { t.Errorf("parseSeconds(%q) accepted", bad) } } for n, want := range map[int]string{43200: "12h", 5400: "1h30m", 90061: "1d1h1m1s", 0: "-"} { if got := fmtSeconds(n); got != want { t.Errorf("fmtSeconds(%d) = %q, want %q", n, got, want) } } } func TestLimitAndDescribe(t *testing.T) { l, err := parseLimit("3/minutes,burst=5,over,per-source") if err != nil || l.Rate != 3 || l.Per != "minute" || l.Burst != 5 || !l.Over || !l.PerSource { t.Errorf("parseLimit: %+v %v", l, err) } if _, err := parseLimit("fast"); err == nil { t.Error("a bad limit accepted") } m := model.Match{InZones: []string{"wan"}, NotSources: true, Sources: []string{"trusted"}, Services: []string{"ssh", "tcp/8080"}} if got := describe(m); got != "in wan from not trusted ssh,tcp/8080" { t.Errorf("describe: %q", got) } if got := editList([]string{"a", "b", "c"}, []string{"d"}, []string{"b"}); len(got) != 3 || got[1] != "c" || got[2] != "d" { t.Errorf("editList: %v", got) } } // TestMatrixAligned: the grid's columns line up in colour too (the // escape codes take no room on screen). func TestMatrixAligned(t *testing.T) { st := model.NewState() st.Zones = []*model.Zone{{ID: 1, Name: "lan", Interfaces: []string{"eth1"}}, {ID: 2, Name: "wan", Interfaces: []string{"wan"}, External: true}} st.Rules = []*model.Rule{{ID: 3, Chain: model.ChainForward, Position: 1, Action: model.ActionAccept, Match: model.Match{InZones: []string{"lan"}, Services: []string{"https"}}}} st.Settings.InputPolicy, st.Settings.ForwardPolicy = model.PolicyDrop, model.PolicyDrop var b strings.Builder writeMatrix(&b, matrix.Build(st), true) esc := regexp.MustCompile("\x1b\\[[0-9]+m") lines := strings.Split(esc.ReplaceAllString(b.String(), ""), "\n") col := strings.Index(lines[0], "wan") for _, l := range lines[1:4] { if r := []rune(l); len(r) <= col || r[col-1] != ' ' || r[col] == ' ' { t.Errorf("misaligned at column %d:\n%s", col, strings.Join(lines[:4], "\n")) break } } if !strings.Contains(b.String(), "\x1b[33mpartly +1") || !strings.Contains(b.String(), "lan → wan\thttps") { t.Errorf("no partly cell, or no list of what's open:\n%s", b.String()) } }