@@ -44,7 +44,6 @@ describe('useScript()', () => {
4444 expect ( state ) . toStrictEqual < ScriptStatus > ( 'loading' ) ;
4545 } ) ;
4646
47- // TODO
4847 it ( 'is in "active" state when the "onload" event was triggered' , async ( ) => {
4948 const { result } = renderHook ( ( ) => useScript ( scriptUrl ) ) ;
5049
@@ -61,6 +60,22 @@ describe('useScript()', () => {
6160 expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'active' ) ;
6261 } ) ;
6362
63+ it ( 'is in "error" state when the "onerror" event was triggered' , async ( ) => {
64+ const { result } = renderHook ( ( ) => useScript ( scriptUrl ) ) ;
65+
66+ expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'loading' ) ;
67+
68+ const element = document . querySelector (
69+ `script[src="${ scriptUrl } "]`
70+ ) as HTMLScriptElement ;
71+
72+ act ( ( ) => {
73+ fireEvent . error ( element ) ;
74+ } ) ;
75+
76+ expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'error' ) ;
77+ } ) ;
78+
6479 it ( 'is in "unloaded" state when the source is removed' , async ( ) => {
6580 const { result } = renderHook ( ( ) => useScript ( scriptUrl ) ) ;
6681
@@ -73,7 +88,7 @@ describe('useScript()', () => {
7388 expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'unloaded' ) ;
7489 } ) ;
7590
76- it ( 'creates a new script and discards the old one when changing the source URL' , async ( ) => {
91+ it ( 'reuses the old script tag when changing the source URL' , async ( ) => {
7792 const newUrl = 'https://test.com/loader.js' ;
7893 const { result } = renderHook ( ( ) => useScript ( scriptUrl ) ) ;
7994
@@ -88,12 +103,11 @@ describe('useScript()', () => {
88103 result . current [ 1 ] ( newUrl ) ;
89104 } ) ;
90105
91- expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'loading' ) ;
92- expect ( element ) . not . toBeInTheDocument ( ) ;
93-
94106 const newElement = document . querySelector (
95107 `script[src="${ newUrl } "]`
96108 ) as HTMLScriptElement ;
109+
110+ expect ( element ) . not . toBeInTheDocument ( ) ;
97111 expect ( newElement ) . toBeInTheDocument ( ) ;
98112 } ) ;
99113
@@ -114,4 +128,56 @@ describe('useScript()', () => {
114128 expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'loading' ) ;
115129 expect ( element ) . toBeInTheDocument ( ) ;
116130 } ) ;
131+
132+ it ( 'handles an existing script' , async ( ) => {
133+ const script = document . createElement ( 'script' ) ;
134+ script . src = scriptUrl ;
135+ document . body . appendChild ( script ) ;
136+
137+ const { result } = renderHook ( ( ) => useScript ( scriptUrl ) ) ;
138+
139+ const element = document . querySelector (
140+ `script[src="${ scriptUrl } "]`
141+ ) as HTMLScriptElement ;
142+
143+ expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'loading' ) ;
144+ expect ( element . src ) . toStrictEqual ( scriptUrl ) ;
145+
146+ act ( ( ) => {
147+ result . current [ 1 ] ( scriptUrl ) ;
148+ } ) ;
149+
150+ expect ( result . current [ 0 ] ) . toStrictEqual < ScriptStatus > ( 'loading' ) ;
151+ expect ( element ) . toBeInTheDocument ( ) ;
152+ } ) ;
153+
154+ it ( 'removes the <script> tag when setting the source to undefined' , async ( ) => {
155+ const { result } = renderHook ( ( ) => useScript ( scriptUrl ) ) ;
156+
157+ const element = document . querySelector (
158+ `script[src="${ scriptUrl } "]`
159+ ) as HTMLScriptElement ;
160+
161+ expect ( element ) . toBeInTheDocument ( ) ;
162+
163+ act ( ( ) => {
164+ result . current [ 1 ] ( ) ;
165+ } ) ;
166+
167+ expect ( element ) . not . toBeInTheDocument ( ) ;
168+ } ) ;
169+
170+ it ( 'removes the <script> tag on unmount' , async ( ) => {
171+ const { unmount } = renderHook ( ( ) => useScript ( scriptUrl ) ) ;
172+
173+ const element = document . querySelector (
174+ `script[src="${ scriptUrl } "]`
175+ ) as HTMLScriptElement ;
176+
177+ expect ( element ) . toBeInTheDocument ( ) ;
178+
179+ unmount ( ) ;
180+
181+ expect ( element ) . not . toBeInTheDocument ( ) ;
182+ } ) ;
117183} ) ;
0 commit comments