@samitouri / QOS-React-1 / commits / af7e8c7a71

Convert trustedTypes to createRoot (#28163)

Sebastian Silbermann committed Jan 30, 2024 at 22:22 UTC af7e8c7a71c60278e3935dfb20fac7b562769bb4
1 file changed +59 -27
packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js
+59 -27
@@ -11,8 +11,9 @@
11
12 describe('when Trusted Types are available in global object', () => {
13 let React;
14 - let ReactDOM;
14 + let ReactDOMClient;
15 let ReactFeatureFlags;
16 + let act;
17 let container;
18 let ttObject1;
19 let ttObject2;
@@ -34,7 +35,8 @@ describe('when Trusted Types are available in global object', () => {
35 ReactFeatureFlags = require('shared/ReactFeatureFlags');
36 ReactFeatureFlags.enableTrustedTypesIntegration = true;
37 React = require('react');
37 - ReactDOM = require('react-dom');
38 + ReactDOMClient = require('react-dom/client');
39 + act = require('internal-test-utils').act;
40 ttObject1 = {
41 toString() {
42 return '<b>Hi</b>';
@@ -53,7 +55,7 @@ describe('when Trusted Types are available in global object', () => {
55 delete window.trustedTypes;
56 });
57
56 - it('should not stringify trusted values for dangerouslySetInnerHTML', () => {
58 + it('should not stringify trusted values for dangerouslySetInnerHTML', async () => {
59 const innerHTMLDescriptor = Object.getOwnPropertyDescriptor(
60 Element.prototype,
61 'innerHTML',
@@ -69,20 +71,21 @@ describe('when Trusted Types are available in global object', () => {
71 return innerHTMLDescriptor.set.apply(this, arguments);
72 },
73 });
72 - ReactDOM.render(
73 - <div dangerouslySetInnerHTML={{__html: ttObject1}} />,
74 - container,
75 - );
74 + const root = ReactDOMClient.createRoot(container);
75 + await act(() => {
76 + root.render(<div dangerouslySetInnerHTML={{__html: ttObject1}} />);
77 + });
78 +
79 expect(container.innerHTML).toBe('<div><b>Hi</b></div>');
80 expect(innerHTMLCalls.length).toBe(1);
81 // Ensure it didn't get stringified when passed to a DOM sink:
82 expect(innerHTMLCalls[0]).toBe(ttObject1);
83
84 innerHTMLCalls.length = 0;
82 - ReactDOM.render(
83 - <div dangerouslySetInnerHTML={{__html: ttObject2}} />,
84 - container,
85 - );
85 + await act(() => {
86 + root.render(<div dangerouslySetInnerHTML={{__html: ttObject2}} />);
87 + });
88 +
89 expect(container.innerHTML).toBe('<div><b>Bye</b></div>');
90 expect(innerHTMLCalls.length).toBe(1);
91 // Ensure it didn't get stringified when passed to a DOM sink:
@@ -96,7 +99,7 @@ describe('when Trusted Types are available in global object', () => {
99 }
100 });
101
99 - it('should not stringify trusted values for setAttribute (unknown attribute)', () => {
102 + it('should not stringify trusted values for setAttribute (unknown attribute)', async () => {
103 const setAttribute = Element.prototype.setAttribute;
104 try {
105 const setAttributeCalls = [];
@@ -104,7 +107,11 @@ describe('when Trusted Types are available in global object', () => {
107 setAttributeCalls.push([this, name.toLowerCase(), value]);
108 return setAttribute.apply(this, arguments);
109 };
107 - ReactDOM.render(<div data-foo={ttObject1} />, container);
110 + const root = ReactDOMClient.createRoot(container);
111 + await act(() => {
112 + root.render(<div data-foo={ttObject1} />);
113 + });
114 +
115 expect(container.innerHTML).toBe('<div data-foo="<b>Hi</b>"></div>');
116 expect(setAttributeCalls.length).toBe(1);
117 expect(setAttributeCalls[0][0]).toBe(container.firstChild);
@@ -113,7 +120,10 @@ describe('when Trusted Types are available in global object', () => {
120 expect(setAttributeCalls[0][2]).toBe(ttObject1);
121
122 setAttributeCalls.length = 0;
116 - ReactDOM.render(<div data-foo={ttObject2} />, container);
123 + await act(() => {
124 + root.render(<div data-foo={ttObject2} />);
125 + });
126 +
127 expect(setAttributeCalls.length).toBe(1);
128 expect(setAttributeCalls[0][0]).toBe(container.firstChild);
129 expect(setAttributeCalls[0][1]).toBe('data-foo');
@@ -124,7 +134,7 @@ describe('when Trusted Types are available in global object', () => {
134 }
135 });
136
127 - it('should not stringify trusted values for setAttribute (known attribute)', () => {
137 + it('should not stringify trusted values for setAttribute (known attribute)', async () => {
138 const setAttribute = Element.prototype.setAttribute;
139 try {
140 const setAttributeCalls = [];
@@ -132,7 +142,11 @@ describe('when Trusted Types are available in global object', () => {
142 setAttributeCalls.push([this, name.toLowerCase(), value]);
143 return setAttribute.apply(this, arguments);
144 };
135 - ReactDOM.render(<div className={ttObject1} />, container);
145 + const root = ReactDOMClient.createRoot(container);
146 + await act(() => {
147 + root.render(<div className={ttObject1} />);
148 + });
149 +
150 expect(container.innerHTML).toBe('<div class="<b>Hi</b>"></div>');
151 expect(setAttributeCalls.length).toBe(1);
152 expect(setAttributeCalls[0][0]).toBe(container.firstChild);
@@ -141,7 +155,10 @@ describe('when Trusted Types are available in global object', () => {
155 expect(setAttributeCalls[0][2]).toBe(ttObject1);
156
157 setAttributeCalls.length = 0;
144 - ReactDOM.render(<div className={ttObject2} />, container);
158 + await act(() => {
159 + root.render(<div className={ttObject2} />);
160 + });
161 +
162 expect(setAttributeCalls.length).toBe(1);
163 expect(setAttributeCalls[0][0]).toBe(container.firstChild);
164 expect(setAttributeCalls[0][1]).toBe('class');
@@ -152,7 +169,7 @@ describe('when Trusted Types are available in global object', () => {
169 }
170 });
171
155 - it('should not stringify trusted values for setAttributeNS', () => {
172 + it('should not stringify trusted values for setAttributeNS', async () => {
173 const setAttributeNS = Element.prototype.setAttributeNS;
174 try {
175 const setAttributeNSCalls = [];
@@ -160,7 +177,11 @@ describe('when Trusted Types are available in global object', () => {
177 setAttributeNSCalls.push([this, ns, name, value]);
178 return setAttributeNS.apply(this, arguments);
179 };
163 - ReactDOM.render(<svg xlinkHref={ttObject1} />, container);
180 + const root = ReactDOMClient.createRoot(container);
181 + await act(() => {
182 + root.render(<svg xlinkHref={ttObject1} />);
183 + });
184 +
185 expect(container.innerHTML).toBe('<svg xlink:href="<b>Hi</b>"></svg>');
186 expect(setAttributeNSCalls.length).toBe(1);
187 expect(setAttributeNSCalls[0][0]).toBe(container.firstChild);
@@ -170,7 +191,10 @@ describe('when Trusted Types are available in global object', () => {
191 expect(setAttributeNSCalls[0][3]).toBe(ttObject1);
192
193 setAttributeNSCalls.length = 0;
173 - ReactDOM.render(<svg xlinkHref={ttObject2} />, container);
194 + await act(() => {
195 + root.render(<svg xlinkHref={ttObject2} />);
196 + });
197 +
198 expect(setAttributeNSCalls.length).toBe(1);
199 expect(setAttributeNSCalls[0][0]).toBe(container.firstChild);
200 expect(setAttributeNSCalls[0][1]).toBe('http://www.w3.org/1999/xlink');
@@ -209,14 +233,17 @@ describe('when Trusted Types are available in global object', () => {
233 });
234
235 // @gate !disableIEWorkarounds
212 - it('should log a warning', () => {
236 + it('should log a warning', async () => {
237 class Component extends React.Component {
238 render() {
239 return <svg dangerouslySetInnerHTML={{__html: 'unsafe html'}} />;
240 }
241 }
218 - expect(() => {
219 - ReactDOM.render(<Component />, container);
242 + const root = ReactDOMClient.createRoot(container);
243 + await expect(async () => {
244 + await act(() => {
245 + root.render(<Component />);
246 + });
247 }).toErrorDev(
248 "Warning: Using 'dangerouslySetInnerHTML' in an svg element with " +
249 'Trusted Types enabled in an Internet Explorer will cause ' +
@@ -229,9 +256,12 @@ describe('when Trusted Types are available in global object', () => {
256 });
257 });
258
232 - it('should warn once when rendering script tag in jsx on client', () => {
233 - expect(() => {
234 - ReactDOM.render(<script>alert("I am not executed")</script>, container);
259 + it('should warn once when rendering script tag in jsx on client', async () => {
260 + const root = ReactDOMClient.createRoot(container);
261 + await expect(async () => {
262 + await act(() => {
263 + root.render(<script>alert("I am not executed")</script>);
264 + });
265 }).toErrorDev(
266 'Warning: Encountered a script tag while rendering React component. ' +
267 'Scripts inside React components are never executed when rendering ' +
@@ -241,6 +271,8 @@ describe('when Trusted Types are available in global object', () => {
271 );
272
273 // check that the warning is printed only once
244 - ReactDOM.render(<script>alert("I am not executed")</script>, container);
274 + await act(() => {
275 + root.render(<script>alert("I am not executed")</script>);
276 + });
277 });
278 });