pwa_test.go 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package controller
  2. import (
  3. "net/http/httptest"
  4. "strings"
  5. "testing"
  6. "testing/fstest"
  7. "github.com/gin-gonic/gin"
  8. )
  9. func TestServePWAAssets(t *testing.T) {
  10. oldDistFS := distFS
  11. distFS = fstest.MapFS{
  12. "dist/manifest.webmanifest": &fstest.MapFile{Data: []byte(`{"name":"3x-ui"}`)},
  13. "dist/pwa-register.js": &fstest.MapFile{Data: []byte("register")},
  14. "dist/service-worker.js": &fstest.MapFile{Data: []byte("worker")},
  15. "dist/icons/3x-ui-192.png": &fstest.MapFile{Data: []byte("icon-192")},
  16. "dist/icons/3x-ui-512.png": &fstest.MapFile{Data: []byte("icon-512")},
  17. }
  18. t.Cleanup(func() { distFS = oldDistFS })
  19. tests := []struct {
  20. name string
  21. handler gin.HandlerFunc
  22. contentType string
  23. body string
  24. }{
  25. {name: "manifest", handler: ServePWAManifest, contentType: "application/manifest+json; charset=utf-8", body: `{"name":"3x-ui"}`},
  26. {name: "registration", handler: ServePWARegister, contentType: "application/javascript; charset=utf-8", body: "register"},
  27. {name: "worker", handler: ServePWAServiceWorker, contentType: "application/javascript; charset=utf-8", body: "worker"},
  28. }
  29. for _, test := range tests {
  30. t.Run(test.name, func(t *testing.T) {
  31. gin.SetMode(gin.TestMode)
  32. response := httptest.NewRecorder()
  33. context, _ := gin.CreateTestContext(response)
  34. test.handler(context)
  35. if response.Code != 200 {
  36. t.Fatalf("status = %d, want 200", response.Code)
  37. }
  38. if response.Header().Get("Content-Type") != test.contentType {
  39. t.Errorf("content type = %q, want %q", response.Header().Get("Content-Type"), test.contentType)
  40. }
  41. if response.Header().Get("Cache-Control") != "no-cache, no-store, must-revalidate" {
  42. t.Errorf("cache control = %q", response.Header().Get("Cache-Control"))
  43. }
  44. if strings.TrimSpace(response.Body.String()) != test.body {
  45. t.Errorf("body = %q, want %q", response.Body.String(), test.body)
  46. }
  47. })
  48. }
  49. }
  50. func TestServePWAIconServesPNG(t *testing.T) {
  51. oldDistFS := distFS
  52. distFS = fstest.MapFS{
  53. "dist/icons/3x-ui-192.png": &fstest.MapFile{Data: []byte("icon-192")},
  54. }
  55. t.Cleanup(func() { distFS = oldDistFS })
  56. gin.SetMode(gin.TestMode)
  57. response := httptest.NewRecorder()
  58. context, _ := gin.CreateTestContext(response)
  59. context.Params = gin.Params{{Key: "name", Value: "3x-ui-192.png"}}
  60. ServePWAIcon(context)
  61. if response.Code != 200 {
  62. t.Fatalf("status = %d, want 200", response.Code)
  63. }
  64. if got := response.Header().Get("Content-Type"); got != "image/png" {
  65. t.Errorf("content type = %q, want %q", got, "image/png")
  66. }
  67. if response.Body.String() != "icon-192" {
  68. t.Errorf("body = %q, want %q", response.Body.String(), "icon-192")
  69. }
  70. }
  71. func TestServePWAIconRejectsUnknownName(t *testing.T) {
  72. oldDistFS := distFS
  73. distFS = fstest.MapFS{}
  74. t.Cleanup(func() { distFS = oldDistFS })
  75. gin.SetMode(gin.TestMode)
  76. response := httptest.NewRecorder()
  77. context, _ := gin.CreateTestContext(response)
  78. context.Params = gin.Params{{Key: "name", Value: "../../etc/passwd"}}
  79. ServePWAIcon(context)
  80. if response.Code != 404 {
  81. t.Fatalf("status = %d, want 404", response.Code)
  82. }
  83. }