package checker import ( "errors" "fmt" "testing" "github.com/pion/stun/v3" ) // TestStunErrorOf_PinPionFormat builds an error using pion's own // ErrorCodeAttribute.String() so that any future change to the format // pion/turn uses ("... (error : )") makes this test fail // loudly instead of silently breaking our diagnostic parsing. func TestStunErrorOf_PinPionFormat(t *testing.T) { cases := []struct { name string code stun.ErrorCode reason string wantCode int wantReason string }{ {"unauthorized", stun.CodeUnauthorized, "Unauthorized", 401, "Unauthorized"}, {"stale nonce", stun.CodeStaleNonce, "Stale Nonce", 438, "Stale Nonce"}, {"server error", stun.CodeServerError, "Server Error", 500, "Server Error"}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { attr := stun.ErrorCodeAttribute{Code: tc.code, Reason: []byte(tc.reason)} // Mirror pion/turn/v4@v4.0.0 client.go:296: // fmt.Errorf("%s (error %s)", res.Type, code) err := fmt.Errorf("error response (error %s)", attr) gotCode, gotReason := stunErrorOf(err) if gotCode != tc.wantCode || gotReason != tc.wantReason { t.Errorf("stunErrorOf(%q) = (%d, %q); want (%d, %q): pion error format may have changed", err.Error(), gotCode, gotReason, tc.wantCode, tc.wantReason) } }) } } func TestStunErrorOf_NoMatch(t *testing.T) { code, reason := stunErrorOf(errors.New("plain error")) if code != 0 { t.Errorf("expected code 0 for unparseable error, got %d", code) } if reason != "plain error" { t.Errorf("expected reason to fall back to message, got %q", reason) } if c, r := stunErrorOf(nil); c != 0 || r != "" { t.Errorf("nil error: got (%d, %q), want (0, \"\")", c, r) } }