@@ -22,58 +22,59 @@ import { setAngularAppTestingManifest } from './testing-utils';
2222describe ( 'AngularServerApp' , ( ) => {
2323 let app : AngularServerApp ;
2424
25- beforeAll ( ( ) => {
26- @Component ( {
27- selector : 'app-home' ,
28- template : `Home works` ,
29- } )
30- class HomeComponent {
31- constructor ( ) {
32- if ( inject ( ActivatedRoute ) . snapshot . data [ 'destroyApp' ] ) {
33- inject ( PlatformRef ) . destroy ( ) ;
34- }
25+ @Component ( {
26+ selector : 'app-home' ,
27+ template : `Home works` ,
28+ } )
29+ class HomeComponent {
30+ constructor ( ) {
31+ if ( inject ( ActivatedRoute ) . snapshot . data [ 'destroyApp' ] ) {
32+ inject ( PlatformRef ) . destroy ( ) ;
3533 }
3634 }
37-
38- @ Component ( {
39- selector : 'app-redirect' ,
40- } )
41- class RedirectComponent {
42- constructor ( ) {
43- const responseInit = inject ( RESPONSE_INIT ) ;
44- if ( responseInit ) {
45- responseInit . status = 308 ;
46- const headers = responseInit . headers ;
47- if ( headers ) {
48- ( headers as Headers ) . set ( 'X-Redirect-Header' , 'custom-value' ) ;
49- }
35+ }
36+
37+ @ Component ( {
38+ selector : 'app-redirect' ,
39+ } )
40+ class RedirectComponent {
41+ constructor ( ) {
42+ const responseInit = inject ( RESPONSE_INIT ) ;
43+ if ( responseInit ) {
44+ responseInit . status = 308 ;
45+ const headers = responseInit . headers ;
46+ if ( headers ) {
47+ ( headers as Headers ) . set ( 'X-Redirect-Header' , 'custom-value' ) ;
5048 }
51-
52- void inject ( Router ) . navigate ( [ ] , {
53- queryParams : { filter : 'test' } ,
54- } ) ;
5549 }
56- }
5750
58- const queryParamAdderGuard : CanActivateFn = ( _route , state ) => {
59- const urlTree = inject ( Router ) . parseUrl ( state . url ) ;
51+ void inject ( Router ) . navigate ( [ ] , {
52+ queryParams : { filter : 'test' } ,
53+ } ) ;
54+ }
55+ }
6056
61- if ( urlTree . queryParamMap . has ( 'filter' ) ) {
62- return true ;
63- }
57+ const queryParamAdderGuard : CanActivateFn = ( _route , state ) => {
58+ const urlTree = inject ( Router ) . parseUrl ( state . url ) ;
6459
65- urlTree . queryParams = {
66- filter : 'test' ,
67- } ;
60+ if ( urlTree . queryParamMap . has ( 'filter' ) ) {
61+ return true ;
62+ }
6863
69- return urlTree ;
64+ urlTree . queryParams = {
65+ filter : 'test' ,
7066 } ;
7167
68+ return urlTree ;
69+ } ;
70+
71+ function setupManifest ( ) : void {
7272 setAngularAppTestingManifest (
7373 [
7474 { path : 'home' , component : HomeComponent } ,
7575 { path : 'home-csr' , component : HomeComponent } ,
7676 { path : 'home-ssg' , component : HomeComponent } ,
77+ { path : 'home-ssg-non-ascii/دليل' , component : HomeComponent } ,
7778 { path : 'page-with-headers' , component : HomeComponent } ,
7879 { path : 'page-with-status' , component : HomeComponent } ,
7980 { path : 'page-destroy-app' , component : HomeComponent , data : { destroyApp : true } } ,
@@ -105,6 +106,10 @@ describe('AngularServerApp', () => {
105106 'X-Some-Header' : 'value' ,
106107 } ,
107108 } ,
109+ {
110+ path : 'home-ssg-non-ascii/دليل' ,
111+ renderMode : RenderMode . Prerender ,
112+ } ,
108113 {
109114 path : 'page-with-status' ,
110115 renderMode : RenderMode . Server ,
@@ -140,6 +145,21 @@ describe('AngularServerApp', () => {
140145 size : 28 ,
141146 hash : 'f799132d0a09e0fef93c68a12e443527700eb59e6f67fcb7854c3a60ff082fde' ,
142147 } ,
148+ 'home-ssg-non-ascii/دليل/index.html' : {
149+ text : async ( ) =>
150+ `<html>
151+ <head>
152+ <title>SSG non-ascii page</title>
153+ <base href="/" />
154+ </head>
155+ <body>
156+ <app-root>Home SSG non-ascii works</app-root>
157+ </body>
158+ </html>
159+ ` ,
160+ size : 38 ,
161+ hash : 'a1b2c3d4e5f6' ,
162+ } ,
143163 } ,
144164 undefined ,
145165 undefined ,
@@ -152,6 +172,10 @@ describe('AngularServerApp', () => {
152172 ) ;
153173
154174 app = new AngularServerApp ( ) ;
175+ }
176+
177+ beforeAll ( ( ) => {
178+ setupManifest ( ) ;
155179 } ) ;
156180
157181 describe ( 'handle' , ( ) => {
@@ -282,6 +306,77 @@ describe('AngularServerApp', () => {
282306 expect ( await response ?. text ( ) ) . toContain ( 'Home SSG works' ) ;
283307 } ) ;
284308
309+ it ( 'should correctly serve prerendered page with non-ASCII path' , async ( ) => {
310+ const response = await app . handle (
311+ new Request ( 'http://localhost/home-ssg-non-ascii/%D8%AF%D9%84%D9%8A%D9%84' ) ,
312+ ) ;
313+ expect ( await response ?. text ( ) ) . toContain ( 'Home SSG non-ascii works' ) ;
314+ } ) ;
315+
316+ it ( `should correctly serve prerendered page with non-ASCII path when the URL ends with 'index.html'` , async ( ) => {
317+ const response = await app . handle (
318+ new Request ( 'http://localhost/home-ssg-non-ascii/%D8%AF%D9%84%D9%8A%D9%84/index.html' ) ,
319+ ) ;
320+ expect ( await response ?. text ( ) ) . toContain ( 'Home SSG non-ascii works' ) ;
321+ } ) ;
322+
323+ it ( 'should correctly serve prerendered page when requested with decoded non-ASCII characters' , async ( ) => {
324+ const response = await app . handle ( new Request ( 'http://localhost/home-ssg-non-ascii/دليل' ) ) ;
325+ expect ( await response ?. text ( ) ) . toContain ( 'Home SSG non-ascii works' ) ;
326+ } ) ;
327+
328+ it ( 'should correctly serve prerendered page with non-ASCII path when baseHref is configured' , async ( ) => {
329+ setAngularAppTestingManifest (
330+ [ { path : 'home-ssg-non-ascii/دليل' , component : HomeComponent } ] ,
331+ [
332+ {
333+ path : 'home-ssg-non-ascii/دليل' ,
334+ renderMode : RenderMode . Prerender ,
335+ } ,
336+ ] ,
337+ '/ar/' ,
338+ {
339+ 'home-ssg-non-ascii/دليل/index.html' : {
340+ text : async ( ) => '<html><body>SSG with baseHref works</body></html>' ,
341+ size : 47 ,
342+ hash : '123456' ,
343+ } ,
344+ } ,
345+ ) ;
346+
347+ const customApp = new AngularServerApp ( ) ;
348+ const response = await customApp . handle (
349+ new Request ( 'http://localhost/ar/home-ssg-non-ascii/%D8%AF%D9%84%D9%8A%D9%84' ) ,
350+ ) ;
351+ expect ( await response ?. text ( ) ) . toContain ( 'SSG with baseHref works' ) ;
352+ } ) ;
353+
354+ it ( 'should correctly serve prerendered page when baseHref contains non-ASCII characters' , async ( ) => {
355+ setAngularAppTestingManifest (
356+ [ { path : 'page' , component : HomeComponent } ] ,
357+ [
358+ {
359+ path : 'page' ,
360+ renderMode : RenderMode . Prerender ,
361+ } ,
362+ ] ,
363+ '/دليل/' ,
364+ {
365+ 'page/index.html' : {
366+ text : async ( ) => '<html><body>SSG with non-ASCII baseHref works</body></html>' ,
367+ size : 57 ,
368+ hash : 'abcdef' ,
369+ } ,
370+ } ,
371+ ) ;
372+
373+ const customApp = new AngularServerApp ( ) ;
374+ const response = await customApp . handle (
375+ new Request ( 'http://localhost/%D8%AF%D9%84%D9%8A%D9%84/page' ) ,
376+ ) ;
377+ expect ( await response ?. text ( ) ) . toContain ( 'SSG with non-ASCII baseHref works' ) ;
378+ } ) ;
379+
285380 it ( 'should return configured headers for pages with specific header settings' , async ( ) => {
286381 const response = await app . handle ( new Request ( 'http://localhost/home-ssg' ) ) ;
287382 const headers = response ?. headers . entries ( ) ?? [ ] ;
0 commit comments