package server

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

	"github.com/gin-gonic/gin"
)

// TestSameOriginGuard checks the admin console's CSRF defence: safe methods pass,
// a state-changing request needs an Origin/Referer host matching the request Host.
func TestSameOriginGuard(t *testing.T) {
	gin.SetMode(gin.TestMode)
	e := gin.New()
	g := e.Group("/_gm")
	g.Use(requireSameOrigin())
	g.POST("/act", func(c *gin.Context) { c.Status(http.StatusOK) })
	g.GET("/page", func(c *gin.Context) { c.Status(http.StatusOK) })

	cases := []struct {
		name    string
		method  string
		path    string
		origin  string
		referer string
		want    int
	}{
		{"get is safe", http.MethodGet, "/_gm/page", "", "", http.StatusOK},
		{"post without origin rejected", http.MethodPost, "/_gm/act", "", "", http.StatusForbidden},
		{"post matching origin ok", http.MethodPost, "/_gm/act", "http://example.com", "", http.StatusOK},
		{"post foreign origin rejected", http.MethodPost, "/_gm/act", "http://evil.test", "", http.StatusForbidden},
		{"post matching referer ok", http.MethodPost, "/_gm/act", "", "http://example.com/_gm/x", http.StatusOK},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			req := httptest.NewRequest(tc.method, "http://example.com"+tc.path, nil)
			if tc.origin != "" {
				req.Header.Set("Origin", tc.origin)
			}
			if tc.referer != "" {
				req.Header.Set("Referer", tc.referer)
			}
			rec := httptest.NewRecorder()
			e.ServeHTTP(rec, req)
			if rec.Code != tc.want {
				t.Errorf("status = %d, want %d", rec.Code, tc.want)
			}
		})
	}
}
