//go:build !lite

package middleware

import (
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestIsUnsafeMethod(t *testing.T) {
	safe := []string{http.MethodGet, http.MethodHead, http.MethodOptions}
	unsafe := []string{http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete}
	for _, m := range safe {
		if IsUnsafeMethod(m) {
			t.Errorf("IsUnsafeMethod(%q) = true, want false", m)
		}
	}
	for _, m := range unsafe {
		if !IsUnsafeMethod(m) {
			t.Errorf("IsUnsafeMethod(%q) = false, want true", m)
		}
	}
}

func TestSameOrigin(t *testing.T) {
	cases := []struct {
		name    string
		host    string
		origin  string
		referer string
		want    bool
	}{
		{"matching origin", "breadbox.example.com", "https://breadbox.example.com", "", true},
		{"mismatched origin", "breadbox.example.com", "https://evil.com", "", false},
		{"referer fallback matches", "breadbox.example.com", "", "https://breadbox.example.com/transactions", true},
		{"referer fallback mismatched", "breadbox.example.com", "", "https://evil.com/x", false},
		{"no origin, no referer", "breadbox.example.com", "", "", false},
		{"origin takes precedence over referer", "breadbox.example.com", "https://evil.com", "https://breadbox.example.com/x", false},
		{"port-sensitive match", "localhost:8081", "http://localhost:8081", "", true},
		{"port-sensitive mismatch", "localhost:8081", "http://localhost:9090", "", false},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			r := httptest.NewRequest(http.MethodPost, "http://"+c.host+"/api/v1/rules", nil)
			r.Host = c.host
			if c.origin != "" {
				r.Header.Set("Origin", c.origin)
			}
			if c.referer != "" {
				r.Header.Set("Referer", c.referer)
			}
			if got := SameOrigin(r); got != c.want {
				t.Errorf("SameOrigin() = %v, want %v", got, c.want)
			}
		})
	}
}
