github.com/levb/mattermost-server@v5.3.1+incompatible/utils/subpath_test.go (about) 1 package utils_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/mattermost/mattermost-server/model" 12 "github.com/mattermost/mattermost-server/utils" 13 ) 14 15 func TestUpdateAssetsSubpath(t *testing.T) { 16 t.Run("no client dir", func(t *testing.T) { 17 tempDir, err := ioutil.TempDir("", "test_update_assets_subpath") 18 require.NoError(t, err) 19 defer os.RemoveAll(tempDir) 20 os.Chdir(tempDir) 21 22 err = utils.UpdateAssetsSubpath("/") 23 require.Error(t, err) 24 }) 25 26 t.Run("valid", func(t *testing.T) { 27 tempDir, err := ioutil.TempDir("", "test_update_assets_subpath") 28 require.NoError(t, err) 29 defer os.RemoveAll(tempDir) 30 os.Chdir(tempDir) 31 32 err = os.Mkdir(model.CLIENT_DIR, 0700) 33 require.NoError(t, err) 34 35 testCases := []struct { 36 Description string 37 RootHTML string 38 MainCSS string 39 ManifestJSON string 40 Subpath string 41 ExpectedRootHTML string 42 ExpectedMainCSS string 43 ExpectedManifestJSON string 44 }{ 45 { 46 "no changes required, empty subpath provided", 47 baseRootHtml, 48 baseCss, 49 baseManifestJson, 50 "", 51 baseRootHtml, 52 baseCss, 53 baseManifestJson, 54 }, 55 { 56 "no changes required", 57 baseRootHtml, 58 baseCss, 59 baseManifestJson, 60 "/", 61 baseRootHtml, 62 baseCss, 63 baseManifestJson, 64 }, 65 { 66 "subpath", 67 baseRootHtml, 68 baseCss, 69 baseManifestJson, 70 "/subpath", 71 subpathRootHtml, 72 subpathCss, 73 subpathManifestJson, 74 }, 75 { 76 "new subpath from old", 77 subpathRootHtml, 78 subpathCss, 79 subpathManifestJson, 80 "/nested/subpath", 81 newSubpathRootHtml, 82 newSubpathCss, 83 newSubpathManifestJson, 84 }, 85 { 86 "resetting to /", 87 subpathRootHtml, 88 subpathCss, 89 baseManifestJson, 90 "/", 91 resetRootHtml, 92 baseCss, 93 baseManifestJson, 94 }, 95 } 96 97 for _, testCase := range testCases { 98 t.Run(testCase.Description, func(t *testing.T) { 99 ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "root.html"), []byte(testCase.RootHTML), 0700) 100 ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "main.css"), []byte(testCase.MainCSS), 0700) 101 ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "manifest.json"), []byte(testCase.ManifestJSON), 0700) 102 err := utils.UpdateAssetsSubpath(testCase.Subpath) 103 require.NoError(t, err) 104 105 contents, err := ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "root.html")) 106 require.NoError(t, err) 107 require.Equal(t, testCase.ExpectedRootHTML, string(contents)) 108 109 contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "main.css")) 110 require.NoError(t, err) 111 require.Equal(t, testCase.ExpectedMainCSS, string(contents)) 112 113 contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "manifest.json")) 114 require.NoError(t, err) 115 require.Equal(t, testCase.ExpectedManifestJSON, string(contents)) 116 }) 117 } 118 }) 119 } 120 121 func TestGetSubpathFromConfig(t *testing.T) { 122 sToP := func(s string) *string { 123 return &s 124 } 125 126 testCases := []struct { 127 Description string 128 SiteURL *string 129 ExpectedError bool 130 ExpectedSubpath string 131 }{ 132 { 133 "empty SiteURL", 134 sToP(""), 135 false, 136 "/", 137 }, 138 { 139 "invalid SiteURL", 140 sToP("cache_object:foo/bar"), 141 true, 142 "", 143 }, 144 { 145 "nil SiteURL", 146 nil, 147 false, 148 "/", 149 }, 150 { 151 "no trailing slash", 152 sToP("http://localhost:8065"), 153 false, 154 "/", 155 }, 156 { 157 "trailing slash", 158 sToP("http://localhost:8065/"), 159 false, 160 "/", 161 }, 162 { 163 "subpath, no trailing slash", 164 sToP("http://localhost:8065/subpath"), 165 false, 166 "/subpath", 167 }, 168 { 169 "trailing slash", 170 sToP("http://localhost:8065/subpath/"), 171 false, 172 "/subpath", 173 }, 174 } 175 176 for _, testCase := range testCases { 177 t.Run(testCase.Description, func(t *testing.T) { 178 config := &model.Config{ 179 ServiceSettings: model.ServiceSettings{ 180 SiteURL: testCase.SiteURL, 181 }, 182 } 183 184 subpath, err := utils.GetSubpathFromConfig(config) 185 if testCase.ExpectedError { 186 require.Error(t, err) 187 } else { 188 require.NoError(t, err) 189 } 190 191 require.Equal(t, testCase.ExpectedSubpath, subpath) 192 }) 193 } 194 } 195 196 const baseRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval'"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style> <link href="/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>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.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>` 197 198 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}` 199 200 const subpathRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval' 'sha256-tPOjw+tkVs9axL78ZwGtYl975dtyPHB6LYKAO2R3gR4='"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/subpath/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/subpath/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/subpath/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/subpath/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/subpath/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/subpath/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/subpath/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/subpath/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/subpath/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/subpath/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/subpath/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/subpath/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style><script>window.publicPath='/subpath/static/'</script> <link href="/subpath/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/subpath/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>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.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>` 201 202 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}` 203 204 const newSubpathRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval' 'sha256-mbRaPRRpWz6MNkX9SyXWMJ8XnWV4w/DoqK2M0ryUAvc='"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/nested/subpath/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/nested/subpath/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/nested/subpath/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/nested/subpath/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/nested/subpath/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/nested/subpath/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/nested/subpath/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/nested/subpath/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/nested/subpath/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/nested/subpath/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/nested/subpath/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/nested/subpath/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style><script>window.publicPath='/nested/subpath/static/'</script> <link href="/nested/subpath/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/nested/subpath/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>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.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>` 205 206 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}` 207 208 const resetRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval' 'sha256-VFw7U/t/OI+I9YMja3c2GDwEQbnlOq/L5+GealgesK8='"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style><script>window.publicPath='/static/'</script> <link href="/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>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.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>` 209 210 const baseManifestJson = `{ 211 "icons": [ 212 { 213 "src": "/static/icon_96x96.png", 214 "sizes": "96x96", 215 "type": "image/png" 216 }, 217 { 218 "src": "/static/icon_32x32.png", 219 "sizes": "32x32", 220 "type": "image/png" 221 }, 222 { 223 "src": "/static/icon_16x16.png", 224 "sizes": "16x16", 225 "type": "image/png" 226 }, 227 { 228 "src": "/static/icon_76x76.png", 229 "sizes": "76x76", 230 "type": "image/png" 231 }, 232 { 233 "src": "/static/icon_72x72.png", 234 "sizes": "72x72", 235 "type": "image/png" 236 }, 237 { 238 "src": "/static/icon_60x60.png", 239 "sizes": "60x60", 240 "type": "image/png" 241 }, 242 { 243 "src": "/static/icon_57x57.png", 244 "sizes": "57x57", 245 "type": "image/png" 246 }, 247 { 248 "src": "/static/icon_152x152.png", 249 "sizes": "152x152", 250 "type": "image/png" 251 }, 252 { 253 "src": "/static/icon_144x144.png", 254 "sizes": "144x144", 255 "type": "image/png" 256 }, 257 { 258 "src": "/static/icon_120x120.png", 259 "sizes": "120x120", 260 "type": "image/png" 261 }, 262 { 263 "src": "/static/icon_192x192.png", 264 "sizes": "192x192", 265 "type": "image/png" 266 } 267 ], 268 "name": "Mattermost", 269 "short_name": "Mattermost", 270 "orientation": "any", 271 "display": "standalone", 272 "start_url": ".", 273 "description": "Mattermost is an open source, self-hosted Slack-alternative", 274 "background_color": "#ffffff" 275 } 276 ` 277 278 const subpathManifestJson = `{ 279 "icons": [ 280 { 281 "src": "/subpath/static/icon_96x96.png", 282 "sizes": "96x96", 283 "type": "image/png" 284 }, 285 { 286 "src": "/subpath/static/icon_32x32.png", 287 "sizes": "32x32", 288 "type": "image/png" 289 }, 290 { 291 "src": "/subpath/static/icon_16x16.png", 292 "sizes": "16x16", 293 "type": "image/png" 294 }, 295 { 296 "src": "/subpath/static/icon_76x76.png", 297 "sizes": "76x76", 298 "type": "image/png" 299 }, 300 { 301 "src": "/subpath/static/icon_72x72.png", 302 "sizes": "72x72", 303 "type": "image/png" 304 }, 305 { 306 "src": "/subpath/static/icon_60x60.png", 307 "sizes": "60x60", 308 "type": "image/png" 309 }, 310 { 311 "src": "/subpath/static/icon_57x57.png", 312 "sizes": "57x57", 313 "type": "image/png" 314 }, 315 { 316 "src": "/subpath/static/icon_152x152.png", 317 "sizes": "152x152", 318 "type": "image/png" 319 }, 320 { 321 "src": "/subpath/static/icon_144x144.png", 322 "sizes": "144x144", 323 "type": "image/png" 324 }, 325 { 326 "src": "/subpath/static/icon_120x120.png", 327 "sizes": "120x120", 328 "type": "image/png" 329 }, 330 { 331 "src": "/subpath/static/icon_192x192.png", 332 "sizes": "192x192", 333 "type": "image/png" 334 } 335 ], 336 "name": "Mattermost", 337 "short_name": "Mattermost", 338 "orientation": "any", 339 "display": "standalone", 340 "start_url": ".", 341 "description": "Mattermost is an open source, self-hosted Slack-alternative", 342 "background_color": "#ffffff" 343 } 344 ` 345 346 const newSubpathManifestJson = `{ 347 "icons": [ 348 { 349 "src": "/nested/subpath/static/icon_96x96.png", 350 "sizes": "96x96", 351 "type": "image/png" 352 }, 353 { 354 "src": "/nested/subpath/static/icon_32x32.png", 355 "sizes": "32x32", 356 "type": "image/png" 357 }, 358 { 359 "src": "/nested/subpath/static/icon_16x16.png", 360 "sizes": "16x16", 361 "type": "image/png" 362 }, 363 { 364 "src": "/nested/subpath/static/icon_76x76.png", 365 "sizes": "76x76", 366 "type": "image/png" 367 }, 368 { 369 "src": "/nested/subpath/static/icon_72x72.png", 370 "sizes": "72x72", 371 "type": "image/png" 372 }, 373 { 374 "src": "/nested/subpath/static/icon_60x60.png", 375 "sizes": "60x60", 376 "type": "image/png" 377 }, 378 { 379 "src": "/nested/subpath/static/icon_57x57.png", 380 "sizes": "57x57", 381 "type": "image/png" 382 }, 383 { 384 "src": "/nested/subpath/static/icon_152x152.png", 385 "sizes": "152x152", 386 "type": "image/png" 387 }, 388 { 389 "src": "/nested/subpath/static/icon_144x144.png", 390 "sizes": "144x144", 391 "type": "image/png" 392 }, 393 { 394 "src": "/nested/subpath/static/icon_120x120.png", 395 "sizes": "120x120", 396 "type": "image/png" 397 }, 398 { 399 "src": "/nested/subpath/static/icon_192x192.png", 400 "sizes": "192x192", 401 "type": "image/png" 402 } 403 ], 404 "name": "Mattermost", 405 "short_name": "Mattermost", 406 "orientation": "any", 407 "display": "standalone", 408 "start_url": ".", 409 "description": "Mattermost is an open source, self-hosted Slack-alternative", 410 "background_color": "#ffffff" 411 } 412 `