package utils_test import ( "io/ioutil" "os" "path/filepath" "testing" "github.com/stretchr/testify/require" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" ) func TestUpdateAssetsSubpath(t *testing.T) { t.Run("no client dir", func(t *testing.T) { tempDir, err := ioutil.TempDir("", "test_update_assets_subpath") require.NoError(t, err) defer os.RemoveAll(tempDir) os.Chdir(tempDir) err = utils.UpdateAssetsSubpath("/") require.Error(t, err) }) t.Run("valid", func(t *testing.T) { tempDir, err := ioutil.TempDir("", "test_update_assets_subpath") require.NoError(t, err) defer os.RemoveAll(tempDir) os.Chdir(tempDir) err = os.Mkdir(model.CLIENT_DIR, 0700) require.NoError(t, err) testCases := []struct { Description string RootHTML string MainCSS string ManifestJSON string Subpath string ExpectedRootHTML string ExpectedMainCSS string ExpectedManifestJSON string }{ { "no changes required, empty subpath provided", baseRootHtml, baseCss, baseManifestJson, "", baseRootHtml, baseCss, baseManifestJson, }, { "no changes required", baseRootHtml, baseCss, baseManifestJson, "/", baseRootHtml, baseCss, baseManifestJson, }, { "subpath", baseRootHtml, baseCss, baseManifestJson, "/subpath", subpathRootHtml, subpathCss, subpathManifestJson, }, { "new subpath from old", subpathRootHtml, subpathCss, subpathManifestJson, "/nested/subpath", newSubpathRootHtml, newSubpathCss, newSubpathManifestJson, }, { "resetting to /", subpathRootHtml, subpathCss, baseManifestJson, "/", resetRootHtml, baseCss, baseManifestJson, }, } for _, testCase := range testCases { t.Run(testCase.Description, func(t *testing.T) { ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "root.html"), []byte(testCase.RootHTML), 0700) ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "main.css"), []byte(testCase.MainCSS), 0700) ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "manifest.json"), []byte(testCase.ManifestJSON), 0700) err := utils.UpdateAssetsSubpath(testCase.Subpath) require.NoError(t, err) contents, err := ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "root.html")) require.NoError(t, err) require.Equal(t, testCase.ExpectedRootHTML, string(contents)) contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "main.css")) require.NoError(t, err) require.Equal(t, testCase.ExpectedMainCSS, string(contents)) contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "manifest.json")) require.NoError(t, err) require.Equal(t, testCase.ExpectedManifestJSON, string(contents)) }) } }) } func TestGetSubpathFromConfig(t *testing.T) { sToP := func(s string) *string { return &s } testCases := []struct { Description string SiteURL *string ExpectedError bool ExpectedSubpath string }{ { "empty SiteURL", sToP(""), false, "/", }, { "invalid SiteURL", sToP("cache_object:foo/bar"), true, "", }, { "nil SiteURL", nil, false, "/", }, { "no trailing slash", sToP("http://localhost:8065"), false, "/", }, { "trailing slash", sToP("http://localhost:8065/"), false, "/", }, { "subpath, no trailing slash", sToP("http://localhost:8065/subpath"), false, "/subpath", }, { "trailing slash", sToP("http://localhost:8065/subpath/"), false, "/subpath", }, } for _, testCase := range testCases { t.Run(testCase.Description, func(t *testing.T) { config := &model.Config{ ServiceSettings: model.ServiceSettings{ SiteURL: testCase.SiteURL, }, } subpath, err := utils.GetSubpathFromConfig(config) if testCase.ExpectedError { require.Error(t, err) } else { require.NoError(t, err) } require.Equal(t, testCase.ExpectedSubpath, subpath) }) } } const baseRootHtml = ` Mattermost

Cannot connect to Mattermost


We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.


` const baseCss = `@font-face{font-family:FontAwesome;src:url(/static/files/674f50d287a8c48dc19ba404d20fe713.eot);src:url(/static/files/674f50d287a8c48dc19ba404d20fe713.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(/static/files/af7ae505a9eed503f8b8e6982036873e.woff2) format("woff2"),url(/static/files/fee66e712a8a08eef5805a46892932ad.woff) format("woff"),url(/static/files/b06871f281fee6b241d60582ae9369b9.ttf) format("truetype"),url(/static/files/677433a0892aaed7b7d2628c313c9775.svg#fontawesomeregular) format("svg");font-weight:400;font-style:normal}` const subpathRootHtml = ` Mattermost

Cannot connect to Mattermost


We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.


` const subpathCss = `@font-face{font-family:FontAwesome;src:url(/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot);src:url(/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(/subpath/static/files/af7ae505a9eed503f8b8e6982036873e.woff2) format("woff2"),url(/subpath/static/files/fee66e712a8a08eef5805a46892932ad.woff) format("woff"),url(/subpath/static/files/b06871f281fee6b241d60582ae9369b9.ttf) format("truetype"),url(/subpath/static/files/677433a0892aaed7b7d2628c313c9775.svg#fontawesomeregular) format("svg");font-weight:400;font-style:normal}` const newSubpathRootHtml = ` Mattermost

Cannot connect to Mattermost


We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.


` const newSubpathCss = `@font-face{font-family:FontAwesome;src:url(/nested/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot);src:url(/nested/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(/nested/subpath/static/files/af7ae505a9eed503f8b8e6982036873e.woff2) format("woff2"),url(/nested/subpath/static/files/fee66e712a8a08eef5805a46892932ad.woff) format("woff"),url(/nested/subpath/static/files/b06871f281fee6b241d60582ae9369b9.ttf) format("truetype"),url(/nested/subpath/static/files/677433a0892aaed7b7d2628c313c9775.svg#fontawesomeregular) format("svg");font-weight:400;font-style:normal}` const resetRootHtml = ` Mattermost

Cannot connect to Mattermost


We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.


` const baseManifestJson = `{ "icons": [ { "src": "/static/icon_96x96.png", "sizes": "96x96", "type": "image/png" }, { "src": "/static/icon_32x32.png", "sizes": "32x32", "type": "image/png" }, { "src": "/static/icon_16x16.png", "sizes": "16x16", "type": "image/png" }, { "src": "/static/icon_76x76.png", "sizes": "76x76", "type": "image/png" }, { "src": "/static/icon_72x72.png", "sizes": "72x72", "type": "image/png" }, { "src": "/static/icon_60x60.png", "sizes": "60x60", "type": "image/png" }, { "src": "/static/icon_57x57.png", "sizes": "57x57", "type": "image/png" }, { "src": "/static/icon_152x152.png", "sizes": "152x152", "type": "image/png" }, { "src": "/static/icon_144x144.png", "sizes": "144x144", "type": "image/png" }, { "src": "/static/icon_120x120.png", "sizes": "120x120", "type": "image/png" }, { "src": "/static/icon_192x192.png", "sizes": "192x192", "type": "image/png" } ], "name": "Mattermost", "short_name": "Mattermost", "orientation": "any", "display": "standalone", "start_url": ".", "description": "Mattermost is an open source, self-hosted Slack-alternative", "background_color": "#ffffff" } ` const subpathManifestJson = `{ "icons": [ { "src": "/subpath/static/icon_96x96.png", "sizes": "96x96", "type": "image/png" }, { "src": "/subpath/static/icon_32x32.png", "sizes": "32x32", "type": "image/png" }, { "src": "/subpath/static/icon_16x16.png", "sizes": "16x16", "type": "image/png" }, { "src": "/subpath/static/icon_76x76.png", "sizes": "76x76", "type": "image/png" }, { "src": "/subpath/static/icon_72x72.png", "sizes": "72x72", "type": "image/png" }, { "src": "/subpath/static/icon_60x60.png", "sizes": "60x60", "type": "image/png" }, { "src": "/subpath/static/icon_57x57.png", "sizes": "57x57", "type": "image/png" }, { "src": "/subpath/static/icon_152x152.png", "sizes": "152x152", "type": "image/png" }, { "src": "/subpath/static/icon_144x144.png", "sizes": "144x144", "type": "image/png" }, { "src": "/subpath/static/icon_120x120.png", "sizes": "120x120", "type": "image/png" }, { "src": "/subpath/static/icon_192x192.png", "sizes": "192x192", "type": "image/png" } ], "name": "Mattermost", "short_name": "Mattermost", "orientation": "any", "display": "standalone", "start_url": ".", "description": "Mattermost is an open source, self-hosted Slack-alternative", "background_color": "#ffffff" } ` const newSubpathManifestJson = `{ "icons": [ { "src": "/nested/subpath/static/icon_96x96.png", "sizes": "96x96", "type": "image/png" }, { "src": "/nested/subpath/static/icon_32x32.png", "sizes": "32x32", "type": "image/png" }, { "src": "/nested/subpath/static/icon_16x16.png", "sizes": "16x16", "type": "image/png" }, { "src": "/nested/subpath/static/icon_76x76.png", "sizes": "76x76", "type": "image/png" }, { "src": "/nested/subpath/static/icon_72x72.png", "sizes": "72x72", "type": "image/png" }, { "src": "/nested/subpath/static/icon_60x60.png", "sizes": "60x60", "type": "image/png" }, { "src": "/nested/subpath/static/icon_57x57.png", "sizes": "57x57", "type": "image/png" }, { "src": "/nested/subpath/static/icon_152x152.png", "sizes": "152x152", "type": "image/png" }, { "src": "/nested/subpath/static/icon_144x144.png", "sizes": "144x144", "type": "image/png" }, { "src": "/nested/subpath/static/icon_120x120.png", "sizes": "120x120", "type": "image/png" }, { "src": "/nested/subpath/static/icon_192x192.png", "sizes": "192x192", "type": "image/png" } ], "name": "Mattermost", "short_name": "Mattermost", "orientation": "any", "display": "standalone", "start_url": ".", "description": "Mattermost is an open source, self-hosted Slack-alternative", "background_color": "#ffffff" } `