|
11 | 11 |
|
12 | 12 | namespace SIL.XForge.Scripture;
|
13 | 13 |
|
| 14 | +/// <summary> |
| 15 | +/// Represents what environment the application is running in. |
| 16 | +/// </summary> |
| 17 | +public enum RunMode |
| 18 | +{ |
| 19 | + Development, |
| 20 | + Production, |
| 21 | +} |
| 22 | + |
14 | 23 | [TestFixture]
|
15 | 24 | public class StartupTests
|
16 | 25 | {
|
@@ -115,6 +124,130 @@ public void IsSpaRoute_ProductionPath_IsRoute()
|
115 | 124 | Assert.IsTrue(actual);
|
116 | 125 | }
|
117 | 126 |
|
| 127 | + private static void IsSpaRoute_Helper(string path, RunMode[] runModes, bool expected) |
| 128 | + { |
| 129 | + foreach (RunMode runMode in runModes) |
| 130 | + { |
| 131 | + var env = new TestEnvironment(runMode.ToString()); |
| 132 | + env.Context.Request.Method = HttpMethods.Get; |
| 133 | + env.Context.Request.Path = new PathString(path); |
| 134 | + // SUT |
| 135 | + bool actual = env.Startup.IsSpaRoute(env.Context); |
| 136 | + Assert.AreEqual(expected, actual, $"Failed for path {path}, runMode {runMode}."); |
| 137 | + } |
| 138 | + } |
| 139 | + |
| 140 | + // SPA route in production and development |
| 141 | + [TestCase("/index.html")] |
| 142 | + [TestCase("/chunk-A1B2C3D4.js")] |
| 143 | + [TestCase("/chunk-A1B2C3D4.js.map")] |
| 144 | + [TestCase("/chunk-E5F6G7H8.js")] |
| 145 | + [TestCase("/chunk-E5F6G7H8.js.map")] |
| 146 | + [TestCase("/main-Y5Z6A1B2.js")] |
| 147 | + [TestCase("/main-Y5Z6A1B2.js.map")] |
| 148 | + [TestCase("/polyfills-C3D4E5F6.js")] |
| 149 | + [TestCase("/polyfills-C3D4E5F6.js.map")] |
| 150 | + [TestCase("/styles-G7H8I9J0.css")] |
| 151 | + [TestCase("/en-M3N4O5P6.js")] |
| 152 | + [TestCase("/en-M3N4O5P6.js.map")] |
| 153 | + [TestCase("/en-Q7R8S9T0.js")] |
| 154 | + [TestCase("/en-Q7R8S9T0.js.map")] |
| 155 | + [TestCase("/quill-U1V2W3X4.js")] |
| 156 | + [TestCase("/quill-U1V2W3X4.js.map")] |
| 157 | + [TestCase("/3rdpartylicenses.txt")] |
| 158 | + [TestCase("/safety-worker.js")] |
| 159 | + [TestCase("/sf-service-worker.js")] |
| 160 | + [TestCase("/ngsw.json")] |
| 161 | + [TestCase("/ngsw-worker.js")] |
| 162 | + [TestCase("/offline.html")] |
| 163 | + [TestCase("/prerendered-routes.json")] |
| 164 | + [TestCase("/manifest.json")] |
| 165 | + [TestCase("/assets/icons/sf-192x192.png")] |
| 166 | + [TestCase("/assets/images/sf_logo_with_name_black.svg")] |
| 167 | + [TestCase("/worker-I9J0K1L2.js")] |
| 168 | + [TestCase("/worker-I9J0K1L2.js.map")] |
| 169 | + [TestCase("/worker-basic.min.js")] |
| 170 | + [TestCase("/node_modules_sillsdev_lynx")] |
| 171 | + [TestCase("/projects")] |
| 172 | + [TestCase("/projects/abc123/translate/GEN/1")] |
| 173 | + [TestCase("/login")] |
| 174 | + [TestCase("/login?sign-up=true")] |
| 175 | + [TestCase("/join/AbCd/en-GB")] |
| 176 | + [TestCase("/callback/auth0?code=1234&state=abcd")] |
| 177 | + [TestCase("/connect-project")] |
| 178 | + [TestCase("/serval-administration")] |
| 179 | + [TestCase("/system-administration")] |
| 180 | + public void IsSpaRoute_ProductionAndDevelopment_True(string path) |
| 181 | + { |
| 182 | + RunMode[] runModes = [RunMode.Production, RunMode.Development]; |
| 183 | + bool expected = true; |
| 184 | + IsSpaRoute_Helper(path, runModes, expected); |
| 185 | + } |
| 186 | + |
| 187 | + // SPA route in development, but not expected in production |
| 188 | + [TestCase("/@vite/client")] |
| 189 | + [TestCase("/@fs/home/user/web-xforge/src/SIL.XForge.Scripture/ClientApp/node_modules/vite/dist/client/env.mjs")] |
| 190 | + // `ng serve` with caching+prebundling can result in files like `main.js`, `polyfill.js`, and `styles.css` with no |
| 191 | + // hashes in the filename. |
| 192 | + [TestCase("/main.js")] |
| 193 | + [TestCase("/polyfills.js")] |
| 194 | + [TestCase("/styles.css")] |
| 195 | + public void IsSpaRoute_Development_True(string path) |
| 196 | + { |
| 197 | + RunMode[] runModes = [RunMode.Development]; |
| 198 | + bool expected = true; |
| 199 | + IsSpaRoute_Helper(path, runModes, expected); |
| 200 | + } |
| 201 | + |
| 202 | + // ASP.NET-handled path in production and development |
| 203 | + [TestCase("/favicon.ico")] |
| 204 | + [TestCase("/css/sf.min.css")] |
| 205 | + [TestCase("/images/EarthLightsSmall.jpg")] |
| 206 | + [TestCase("/scss/mixins/_breakpoints.scss")] |
| 207 | + [TestCase("/scss/sf.scss")] |
| 208 | + [TestCase("/images/multi-devices.svg")] |
| 209 | + [TestCase("/images/community-checking.svg")] |
| 210 | + [TestCase("/images/quoter.jpg")] |
| 211 | + [TestCase("/terms")] |
| 212 | + [TestCase("/privacy")] |
| 213 | + [TestCase("/lib/material-design-lite/js/material.min.js")] |
| 214 | + [TestCase("/lib/material-design-lite/css/material.sf_grey-pt_green.min.css")] |
| 215 | + [TestCase("/non-existent-page")] |
| 216 | + [TestCase("/?login")] |
| 217 | + [TestCase("/?/login")] |
| 218 | + [TestCase("//?login")] |
| 219 | + [TestCase("//?/login")] |
| 220 | + [TestCase("/??login")] |
| 221 | + [TestCase("/??/login")] |
| 222 | + [TestCase("/#login")] |
| 223 | + [TestCase("/#/login")] |
| 224 | + // It may or may not be possible for the path to be the empty string. If it is, let's have ASP.NET handle it. |
| 225 | + [TestCase("")] |
| 226 | + // The paths "/", "/Index", and "/Status/Error" are handled by ASP.NET and don't even get to IsSpaRoute. If they did |
| 227 | + // for some reason, we'll have IsSpaRoute return false. |
| 228 | + [TestCase("/")] |
| 229 | + [TestCase("/Index")] |
| 230 | + [TestCase("/Status/Error")] |
| 231 | + // Paths with a beginning that start to match an SPA path, but ultimately don't, can be handled by ASP.NET. |
| 232 | + [TestCase("/mainly")] |
| 233 | + [TestCase("/enquiry")] |
| 234 | + [TestCase("/workerbee")] |
| 235 | + public void IsSpaRoute_ProductionAndDevelopment_False(string path) |
| 236 | + { |
| 237 | + RunMode[] runModes = [RunMode.Production, RunMode.Development]; |
| 238 | + bool expected = false; |
| 239 | + IsSpaRoute_Helper(path, runModes, expected); |
| 240 | + } |
| 241 | + |
| 242 | + // ASP.NET-handled path in development, but not expected in production |
| 243 | + [TestCase("/_framework/aspnetcore-browser-refresh.js")] |
| 244 | + public void IsSpaRoute_Development_False(string path) |
| 245 | + { |
| 246 | + RunMode[] runModes = [RunMode.Development]; |
| 247 | + bool expected = false; |
| 248 | + IsSpaRoute_Helper(path, runModes, expected); |
| 249 | + } |
| 250 | + |
118 | 251 | private class TestEnvironment
|
119 | 252 | {
|
120 | 253 | public TestEnvironment(string? environmentName = null)
|
|
0 commit comments