package main import ( "bytes" "context" "errors" "git.ipao.vip/rogee/go-sip/internal/sipcall" "os" "path/filepath" "strings" "testing" ) func testLineENV(t *testing.T) string { t.Helper() env := filepath.Join(t.TempDir(), "line.env") data := `SIP_ID=line SIP_SERVER=192.0.2.1 SIP_PORT=5060 SIP_CALLER_ID=BD123 SIP_PREFIX=7089 SIP_TRANSPORT=udp SIP_AUTH=ip SIP_REGISTER=no SIP_CODEC=alaw ASTERISK_CONFIG_DIR=/tmp/ast ASTERISK_BIN=/usr/local/sbin/asterisk ASTERISK_LIBRARY_DIR=/usr/local/lib OUTPUT_DIR=/tmp/results RING_SECONDS=20 HOLD_SECONDS=3 DEBUG_INTERFACE=any ` if err := os.WriteFile(env, []byte(data), 0600); err != nil { t.Fatal(err) } return env } func TestCallCLIHasNoBusinessOrAIDependencies(t *testing.T) { env := testLineENV(t) for _, tc := range []struct { args []string debug bool }{ {[]string{env, "18601010101"}, false}, {[]string{"-D", env, "18601010101"}, true}, {[]string{"--debug", env, "18601010101"}, true}, {[]string{env, "-D", "18601010101"}, true}, {[]string{env, "--debug", "18601010101"}, true}, } { calls := 0 root := newRootCommand(func(ctx context.Context, c sipcall.Config, n string, debug bool) (*sipcall.Report, error) { calls++ if debug != tc.debug || n != "18601010101" || c.ID != "line" { t.Fatal("incorrect CLI inputs") } return &sipcall.Report{Status: "connected", Directory: "/tmp/result", Callee: n, DialedCallee: c.Prefix + n, Debug: debug}, nil }) out := &bytes.Buffer{} root.SetOut(out) root.SetErr(out) root.SetArgs(tc.args) if err := root.Execute(); err != nil || calls != 1 { t.Fatalf("%v %v", tc.args, err) } if !strings.Contains(out.String(), "result.json") { t.Fatal("result path missing") } } } func TestCallCLIRejectsMissingOrMalformedInputsBeforeHostAccess(t *testing.T) { env := testLineENV(t) for _, args := range [][]string{ {}, {"-D"}, {env}, {env, "123", "456"}, {"missing.env", "123"}, {env, "+123"}, {env, ""}, {env, strings.Repeat("1", 33)}, {env, "123"}, {"--unknown", env, "123"}, {"agent"}, {"call", "123"}, {"call", env, "123"}, {"call", "--sip", env, "123"}, {"--sip", env, "123"}, } { root := newRootCommand(func(context.Context, sipcall.Config, string, bool) (*sipcall.Report, error) { t.Fatal("invalid input must never access host") return nil, nil }) root.SetArgs(args) root.SetOut(&bytes.Buffer{}) root.SetErr(&bytes.Buffer{}) if err := root.Execute(); err == nil { t.Fatalf("invalid invocation accepted: %v", args) } } } func TestCallCLIHelpShowsPositionalArguments(t *testing.T) { root := newRootCommand(func(context.Context, sipcall.Config, string, bool) (*sipcall.Report, error) { t.Fatal("help must never access host") return nil, nil }) out := &bytes.Buffer{} root.SetOut(out) root.SetArgs([]string{"--help"}) if err := root.Execute(); err != nil { t.Fatal(err) } for _, text := range []string{"sip-call <线路.env> <原始号码>", "-D, --debug"} { if !strings.Contains(out.String(), text) { t.Fatalf("help is missing %q: %s", text, out.String()) } } if strings.Contains(out.String(), "--sip") || strings.Contains(out.String(), "Available Commands:") { t.Fatalf("help still advertises subcommands or --sip: %s", out.String()) } } func TestCallCLIPropagatesRunFailure(t *testing.T) { want := errors.New("unconfirmed call") root := newRootCommand(func(context.Context, sipcall.Config, string, bool) (*sipcall.Report, error) { return &sipcall.Report{Status: "unknown", Directory: "/tmp/test"}, want }) root.SetOut(&bytes.Buffer{}) root.SetArgs([]string{testLineENV(t), "18601010101"}) if err := root.Execute(); !errors.Is(err, want) { t.Fatalf("run failure hidden: %v", err) } } func TestDebugStartupFailureDoesNotClaimCaptureDisabled(t *testing.T) { out := &bytes.Buffer{} err := printReport(out, &sipcall.Report{Status: "not_dialed", Directory: "/tmp/test", Debug: true, Failure: "tcpdump startup failed"}) if err != nil { t.Fatal(err) } if strings.Contains(out.String(), "抓包:未启用") || !strings.Contains(out.String(), "抓包:已请求,但未启动") { t.Fatalf("debug failure was reported as disabled: %s", out.String()) } } func TestCallCLIDoesNotHideRunFailures(t *testing.T) { errExpected := errors.New("unconfirmed call") out := &bytes.Buffer{} err := printReport(out, &sipcall.Report{Status: "unknown", Directory: "/tmp/test", Failure: errExpected.Error()}) if err != nil || !strings.Contains(out.String(), "状态不明") { t.Fatal("unknown call must not look connected") } }