package server import ( "encoding/json" "fmt" "net/http/httptest" "os" "regexp" "strconv" "strings" "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/consts" "github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/tests" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("serveIndex", func() { var ds model.DataStore mockUser := &mockedUserRepo{} fs := os.DirFS("tests/fixtures") BeforeEach(func() { ds = &tests.MockDataStore{MockedUser: mockUser} conf.Server.UILoginBackgroundURL = "" }) It("adds app_config to index.html", func() { r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) Expect(w.Code).To(Equal(200)) config := extractAppConfig(w.Body.String()) Expect(config).To(BeAssignableToTypeOf(map[string]interface{}{})) }) It("sets firstTime = true when User table is empty", func() { mockUser.empty = true r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("firstTime", true)) }) It("sets firstTime = false when User table is not empty", func() { mockUser.empty = false r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("firstTime", false)) }) It("sets baseURL", func() { conf.Server.BaseURL = "base_url_test" r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("baseURL", "base_url_test")) }) It("sets the uiLoginBackgroundURL", func() { conf.Server.UILoginBackgroundURL = "my_background_url" r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("loginBackgroundURL", "my_background_url")) }) It("sets the welcomeMessage", func() { conf.Server.UIWelcomeMessage = "Hello" r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("welcomeMessage", "Hello")) }) It("sets the enableTranscodingConfig", func() { conf.Server.EnableTranscodingConfig = true r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("enableTranscodingConfig", true)) }) It("sets the enableDownloads", func() { conf.Server.EnableDownloads = true r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("enableDownloads", true)) }) It("sets the enableLoved", func() { conf.Server.EnableFavourites = true r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("enableFavourites", true)) }) It("sets the enableStarRating", func() { conf.Server.EnableStarRating = true r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("enableStarRating", true)) }) It("sets the defaultTheme", func() { conf.Server.DefaultTheme = "Light" r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("defaultTheme", "Light")) }) It("sets the enableCoverAnimation", func() { conf.Server.EnableCoverAnimation = true r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("enableCoverAnimation", true)) }) It("sets the gaTrackingId", func() { conf.Server.GATrackingID = "UA-12345" r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("gaTrackingId", "UA-12345")) }) It("sets the version", func() { r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("version", consts.Version())) }) It("sets the losslessFormats", func() { r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) expected := strings.ToUpper(strings.Join(consts.LosslessFormats, ",")) Expect(config).To(HaveKeyWithValue("losslessFormats", expected)) }) It("sets the enableUserEditing", func() { r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("enableUserEditing", true)) }) It("sets the devEnableShare", func() { r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("devEnableShare", false)) }) It("sets the lastFMEnabled", func() { r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("lastFMEnabled", true)) }) It("sets the lastFMApiKey", func() { conf.Server.LastFM.ApiKey = "APIKEY-123" r := httptest.NewRequest("GET", "/index.html", nil) w := httptest.NewRecorder() serveIndex(ds, fs)(w, r) config := extractAppConfig(w.Body.String()) Expect(config).To(HaveKeyWithValue("lastFMApiKey", "APIKEY-123")) }) }) var appConfigRegex = regexp.MustCompile(`(?m)window.__APP_CONFIG__="([^"]*)`) func extractAppConfig(body string) map[string]interface{} { config := make(map[string]interface{}) match := appConfigRegex.FindStringSubmatch(body) if match == nil { return config } str, err := strconv.Unquote("\"" + match[1] + "\"") if err != nil { panic(fmt.Sprintf("%s: %s", match[1], err)) } if err := json.Unmarshal([]byte(str), &config); err != nil { panic(err) } return config } type mockedUserRepo struct { model.UserRepository empty bool } func (u *mockedUserRepo) CountAll(...model.QueryOptions) (int64, error) { if u.empty { return 0, nil } return 1, nil }