@@ -1001,6 +1001,118 @@ describe('MatIcon', () => {
1001
1001
1002
1002
} ) ;
1003
1003
1004
+ describe ( 'Icons resolved through a resolver function' , ( ) => {
1005
+ it ( 'should resolve icons through a resolver function' , fakeAsync ( ( ) => {
1006
+ iconRegistry . addSvgIconResolver ( name => {
1007
+ if ( name === 'fluffy' ) {
1008
+ return trustUrl ( 'cat.svg' ) ;
1009
+ } else if ( name === 'fido' ) {
1010
+ return trustUrl ( 'dog.svg' ) ;
1011
+ } else if ( name === 'felix' ) {
1012
+ return { url : trustUrl ( 'auth-cat.svg' ) , options : { withCredentials : true } } ;
1013
+ }
1014
+ return null ;
1015
+ } ) ;
1016
+
1017
+ const fixture = TestBed . createComponent ( IconFromSvgName ) ;
1018
+ let svgElement : SVGElement ;
1019
+ let testRequest : TestRequest ;
1020
+ const testComponent = fixture . componentInstance ;
1021
+ const iconElement = fixture . debugElement . nativeElement . querySelector ( 'mat-icon' ) ;
1022
+
1023
+ testComponent . iconName = 'fido' ;
1024
+ fixture . detectChanges ( ) ;
1025
+ http . expectOne ( 'dog.svg' ) . flush ( FAKE_SVGS . dog ) ;
1026
+ svgElement = verifyAndGetSingleSvgChild ( iconElement ) ;
1027
+ verifyPathChildElement ( svgElement , 'woof' ) ;
1028
+
1029
+ // Change the icon, and the SVG element should be replaced.
1030
+ testComponent . iconName = 'fluffy' ;
1031
+ fixture . detectChanges ( ) ;
1032
+ http . expectOne ( 'cat.svg' ) . flush ( FAKE_SVGS . cat ) ;
1033
+ svgElement = verifyAndGetSingleSvgChild ( iconElement ) ;
1034
+ verifyPathChildElement ( svgElement , 'meow' ) ;
1035
+
1036
+ // Using an icon from a previously loaded URL should not cause another HTTP request.
1037
+ testComponent . iconName = 'fido' ;
1038
+ fixture . detectChanges ( ) ;
1039
+ http . expectNone ( 'dog.svg' ) ;
1040
+ svgElement = verifyAndGetSingleSvgChild ( iconElement ) ;
1041
+ verifyPathChildElement ( svgElement , 'woof' ) ;
1042
+
1043
+ // Change icon to one that needs credentials during fetch.
1044
+ testComponent . iconName = 'felix' ;
1045
+ fixture . detectChanges ( ) ;
1046
+ testRequest = http . expectOne ( 'auth-cat.svg' ) ;
1047
+ expect ( testRequest . request . withCredentials ) . toBeTrue ( ) ;
1048
+ testRequest . flush ( FAKE_SVGS . cat ) ;
1049
+ svgElement = verifyAndGetSingleSvgChild ( iconElement ) ;
1050
+ verifyPathChildElement ( svgElement , 'meow' ) ;
1051
+
1052
+ // Assert that a registered icon can be looked-up by url.
1053
+ iconRegistry . getSvgIconFromUrl ( trustUrl ( 'cat.svg' ) ) . subscribe ( element => {
1054
+ verifyPathChildElement ( element , 'meow' ) ;
1055
+ } ) ;
1056
+
1057
+ tick ( ) ;
1058
+ } ) ) ;
1059
+
1060
+ it ( 'should fall back to second resolver if the first one returned null' , fakeAsync ( ( ) => {
1061
+ iconRegistry
1062
+ . addSvgIconResolver ( ( ) => null )
1063
+ . addSvgIconResolver ( name => name === 'fido' ? trustUrl ( 'dog.svg' ) : null ) ;
1064
+
1065
+ const fixture = TestBed . createComponent ( IconFromSvgName ) ;
1066
+ const iconElement = fixture . debugElement . nativeElement . querySelector ( 'mat-icon' ) ;
1067
+
1068
+ fixture . componentInstance . iconName = 'fido' ;
1069
+ fixture . detectChanges ( ) ;
1070
+ http . expectOne ( 'dog.svg' ) . flush ( FAKE_SVGS . dog ) ;
1071
+ verifyPathChildElement ( verifyAndGetSingleSvgChild ( iconElement ) , 'woof' ) ;
1072
+ tick ( ) ;
1073
+ } ) ) ;
1074
+
1075
+ it ( 'should be able to set the viewBox when resolving an icon with a function' , fakeAsync ( ( ) => {
1076
+ iconRegistry . addSvgIconResolver ( name => {
1077
+ if ( name === 'fluffy' ) {
1078
+ return { url : trustUrl ( 'cat.svg' ) , options : { viewBox : '0 0 27 27' } } ;
1079
+ } else if ( name === 'fido' ) {
1080
+ return { url : trustUrl ( 'dog.svg' ) , options : { viewBox : '0 0 43 43' } } ;
1081
+ }
1082
+ return null ;
1083
+ } ) ;
1084
+
1085
+ const fixture = TestBed . createComponent ( IconFromSvgName ) ;
1086
+ let svgElement : SVGElement ;
1087
+ const testComponent = fixture . componentInstance ;
1088
+ const iconElement = fixture . debugElement . nativeElement . querySelector ( 'mat-icon' ) ;
1089
+
1090
+ testComponent . iconName = 'fido' ;
1091
+ fixture . detectChanges ( ) ;
1092
+ http . expectOne ( 'dog.svg' ) . flush ( FAKE_SVGS . dog ) ;
1093
+ svgElement = verifyAndGetSingleSvgChild ( iconElement ) ;
1094
+ expect ( svgElement . getAttribute ( 'viewBox' ) ) . toBe ( '0 0 43 43' ) ;
1095
+
1096
+ // Change the icon, and the SVG element should be replaced.
1097
+ testComponent . iconName = 'fluffy' ;
1098
+ fixture . detectChanges ( ) ;
1099
+ http . expectOne ( 'cat.svg' ) . flush ( FAKE_SVGS . cat ) ;
1100
+ svgElement = verifyAndGetSingleSvgChild ( iconElement ) ;
1101
+ expect ( svgElement . getAttribute ( 'viewBox' ) ) . toBe ( '0 0 27 27' ) ;
1102
+ } ) ) ;
1103
+
1104
+ it ( 'should throw an error when the resolver returns an untrusted URL' , ( ) => {
1105
+ iconRegistry . addSvgIconResolver ( ( ) => 'not-trusted.svg' ) ;
1106
+
1107
+ expect ( ( ) => {
1108
+ const fixture = TestBed . createComponent ( IconFromSvgName ) ;
1109
+ fixture . componentInstance . iconName = 'fluffy' ;
1110
+ fixture . detectChanges ( ) ;
1111
+ } ) . toThrowError ( / u n s a f e v a l u e u s e d i n a r e s o u r c e U R L c o n t e x t / ) ;
1112
+ } ) ;
1113
+
1114
+ } ) ;
1115
+
1004
1116
it ( 'should handle assigning an icon through the setter' , fakeAsync ( ( ) => {
1005
1117
iconRegistry . addSvgIconLiteral ( 'fido' , trustHtml ( FAKE_SVGS . dog ) ) ;
1006
1118
0 commit comments