package controller import ( "net/http/httptest" "strings" "testing" "testing/fstest" "github.com/gin-gonic/gin" ) func TestServePWAAssets(t *testing.T) { oldDistFS := distFS distFS = fstest.MapFS{ "dist/manifest.webmanifest": &fstest.MapFile{Data: []byte(`{"name":"3x-ui"}`)}, "dist/pwa-register.js": &fstest.MapFile{Data: []byte("register")}, "dist/service-worker.js": &fstest.MapFile{Data: []byte("worker")}, "dist/icons/3x-ui-192.png": &fstest.MapFile{Data: []byte("icon-192")}, "dist/icons/3x-ui-512.png": &fstest.MapFile{Data: []byte("icon-512")}, } t.Cleanup(func() { distFS = oldDistFS }) tests := []struct { name string handler gin.HandlerFunc contentType string body string }{ {name: "manifest", handler: ServePWAManifest, contentType: "application/manifest+json; charset=utf-8", body: `{"name":"3x-ui"}`}, {name: "registration", handler: ServePWARegister, contentType: "application/javascript; charset=utf-8", body: "register"}, {name: "worker", handler: ServePWAServiceWorker, contentType: "application/javascript; charset=utf-8", body: "worker"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { gin.SetMode(gin.TestMode) response := httptest.NewRecorder() context, _ := gin.CreateTestContext(response) test.handler(context) if response.Code != 200 { t.Fatalf("status = %d, want 200", response.Code) } if response.Header().Get("Content-Type") != test.contentType { t.Errorf("content type = %q, want %q", response.Header().Get("Content-Type"), test.contentType) } if response.Header().Get("Cache-Control") != "no-cache, no-store, must-revalidate" { t.Errorf("cache control = %q", response.Header().Get("Cache-Control")) } if strings.TrimSpace(response.Body.String()) != test.body { t.Errorf("body = %q, want %q", response.Body.String(), test.body) } }) } } func TestServePWAIconServesPNG(t *testing.T) { oldDistFS := distFS distFS = fstest.MapFS{ "dist/icons/3x-ui-192.png": &fstest.MapFile{Data: []byte("icon-192")}, } t.Cleanup(func() { distFS = oldDistFS }) gin.SetMode(gin.TestMode) response := httptest.NewRecorder() context, _ := gin.CreateTestContext(response) context.Params = gin.Params{{Key: "name", Value: "3x-ui-192.png"}} ServePWAIcon(context) if response.Code != 200 { t.Fatalf("status = %d, want 200", response.Code) } if got := response.Header().Get("Content-Type"); got != "image/png" { t.Errorf("content type = %q, want %q", got, "image/png") } if response.Body.String() != "icon-192" { t.Errorf("body = %q, want %q", response.Body.String(), "icon-192") } } func TestServePWAIconRejectsUnknownName(t *testing.T) { oldDistFS := distFS distFS = fstest.MapFS{} t.Cleanup(func() { distFS = oldDistFS }) gin.SetMode(gin.TestMode) response := httptest.NewRecorder() context, _ := gin.CreateTestContext(response) context.Params = gin.Params{{Key: "name", Value: "../../etc/passwd"}} ServePWAIcon(context) if response.Code != 404 { t.Fatalf("status = %d, want 404", response.Code) } }