mirror of
https://github.com/aykhans/sarin.git
synced 2026-02-28 06:49:13 +00:00
Add e2e tests
This commit is contained in:
331
e2e/request_test.go
Normal file
331
e2e/request_test.go
Normal file
@@ -0,0 +1,331 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"slices"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMethodGET(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Method != http.MethodGet {
|
||||
t.Errorf("expected default method GET, got %s", req.Method)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethodPOST(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-M", "POST", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Method != http.MethodPost {
|
||||
t.Errorf("expected method POST, got %s", req.Method)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethodExplicit(t *testing.T) {
|
||||
t.Parallel()
|
||||
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"}
|
||||
for _, method := range methods {
|
||||
t.Run(method, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-M", method, "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Method != method {
|
||||
t.Errorf("expected method %s, got %s", method, req.Method)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleMethods(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
// With multiple methods, sarin cycles through them
|
||||
res := run("-U", cs.URL, "-r", "4", "-M", "GET", "-M", "POST", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
reqs := cs.allRequests()
|
||||
if len(reqs) != 4 {
|
||||
t.Fatalf("expected 4 requests, got %d", len(reqs))
|
||||
}
|
||||
|
||||
// Should see both GET and POST used
|
||||
methods := make(map[string]bool)
|
||||
for _, r := range reqs {
|
||||
methods[r.Method] = true
|
||||
}
|
||||
if !methods["GET"] || !methods["POST"] {
|
||||
t.Errorf("expected both GET and POST to be used, got methods: %v", methods)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingleHeader(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-H", "X-Custom: hello", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
vals, ok := req.Headers["X-Custom"]
|
||||
if !ok {
|
||||
t.Fatalf("expected X-Custom header, got headers: %v", req.Headers)
|
||||
}
|
||||
if len(vals) != 1 || vals[0] != "hello" {
|
||||
t.Errorf("expected X-Custom: [hello], got %v", vals)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1",
|
||||
"-H", "X-First: one",
|
||||
"-H", "X-Second: two",
|
||||
"-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Headers["X-First"]; len(v) == 0 || v[0] != "one" {
|
||||
t.Errorf("expected X-First: one, got %v", v)
|
||||
}
|
||||
if v := req.Headers["X-Second"]; len(v) == 0 || v[0] != "two" {
|
||||
t.Errorf("expected X-Second: two, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaderWithEmptyValue(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
// Header without ": " separator should have empty value
|
||||
res := run("-U", cs.URL, "-r", "1", "-H", "X-Empty", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if _, ok := req.Headers["X-Empty"]; !ok {
|
||||
t.Errorf("expected X-Empty header to be present, got headers: %v", req.Headers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultUserAgentHeader(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
ua, ok := req.Headers["User-Agent"]
|
||||
if !ok || len(ua) == 0 {
|
||||
t.Fatalf("expected User-Agent header, got headers: %v", req.Headers)
|
||||
}
|
||||
assertContains(t, ua[0], "Sarin/")
|
||||
}
|
||||
|
||||
func TestCustomUserAgentOverridesDefault(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-H", "User-Agent: MyAgent/1.0", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
ua := req.Headers["User-Agent"]
|
||||
if len(ua) == 0 {
|
||||
t.Fatal("expected User-Agent header")
|
||||
}
|
||||
// When user sets User-Agent, the default should not be added
|
||||
if slices.Contains(ua, "MyAgent/1.0") {
|
||||
return // found the custom one
|
||||
}
|
||||
t.Errorf("expected custom User-Agent 'MyAgent/1.0', got %v", ua)
|
||||
}
|
||||
|
||||
func TestSingleParam(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-P", "key1=value1", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
vals, ok := req.Query["key1"]
|
||||
if !ok {
|
||||
t.Fatalf("expected key1 param, got query: %v", req.Query)
|
||||
}
|
||||
if len(vals) != 1 || vals[0] != "value1" {
|
||||
t.Errorf("expected key1=[value1], got %v", vals)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1",
|
||||
"-P", "a=1",
|
||||
"-P", "b=2",
|
||||
"-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Query["a"]; len(v) == 0 || v[0] != "1" {
|
||||
t.Errorf("expected a=1, got %v", v)
|
||||
}
|
||||
if v := req.Query["b"]; len(v) == 0 || v[0] != "2" {
|
||||
t.Errorf("expected b=2, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamsFromURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
// Params in the URL itself should be extracted and sent
|
||||
res := run("-U", cs.URL+"?fromurl=yes", "-r", "1", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Query["fromurl"]; len(v) == 0 || v[0] != "yes" {
|
||||
t.Errorf("expected fromurl=yes from URL query, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamsFromURLAndFlag(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
// Both URL params and -P params should be sent
|
||||
res := run("-U", cs.URL+"?fromurl=yes", "-r", "1", "-P", "fromflag=also", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Query["fromurl"]; len(v) == 0 || v[0] != "yes" {
|
||||
t.Errorf("expected fromurl=yes, got %v", v)
|
||||
}
|
||||
if v := req.Query["fromflag"]; len(v) == 0 || v[0] != "also" {
|
||||
t.Errorf("expected fromflag=also, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingleCookie(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-C", "session=abc123", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v, ok := req.Cookies["session"]; !ok || v != "abc123" {
|
||||
t.Errorf("expected cookie session=abc123, got cookies: %v", req.Cookies)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleCookies(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1",
|
||||
"-C", "session=abc",
|
||||
"-C", "token=xyz",
|
||||
"-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v, ok := req.Cookies["session"]; !ok || v != "abc" {
|
||||
t.Errorf("expected cookie session=abc, got %v", req.Cookies)
|
||||
}
|
||||
if v, ok := req.Cookies["token"]; !ok || v != "xyz" {
|
||||
t.Errorf("expected cookie token=xyz, got %v", req.Cookies)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBody(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL, "-r", "1", "-M", "POST", "-B", "hello world", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Body != "hello world" {
|
||||
t.Errorf("expected body 'hello world', got %q", req.Body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBodyJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
jsonBody := `{"name":"test","value":42}`
|
||||
res := run("-U", cs.URL, "-r", "1", "-M", "POST", "-B", jsonBody, "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Body != jsonBody {
|
||||
t.Errorf("expected body %q, got %q", jsonBody, req.Body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestURLPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
res := run("-U", cs.URL+"/api/v1/users", "-r", "1", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Path != "/api/v1/users" {
|
||||
t.Errorf("expected path /api/v1/users, got %s", req.Path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamWithEmptyValue(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
// Param without = value
|
||||
res := run("-U", cs.URL, "-r", "1", "-P", "empty", "-q", "-o", "json")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if _, ok := req.Query["empty"]; !ok {
|
||||
t.Errorf("expected 'empty' param to be present, got query: %v", req.Query)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user