@@ -153,27 +153,166 @@ describe("GoogleAnalyticsWorkaround", () => {
153153
154154 expect ( scriptContent ) . toContain ( "gtag('config', 'G-CUSTOM456'" ) ;
155155 } ) ;
156+
157+ it ( "sets debug_mode to false when debugMode prop is false" , ( ) => {
158+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" debugMode = { false } /> ) ;
159+
160+ const initScript = screen . getByTestId ( "_next-ga-init" ) ;
161+ const scriptContent = initScript . innerHTML ;
162+
163+ expect ( scriptContent ) . toContain ( "'debug_mode': false" ) ;
164+ } ) ;
165+
166+ it ( "includes gtag function definition in the init script" , ( ) => {
167+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" /> ) ;
168+
169+ const initScript = screen . getByTestId ( "_next-ga-init" ) ;
170+ const scriptContent = initScript . innerHTML ;
171+
172+ expect ( scriptContent ) . toContain ( "function gtag()" ) ;
173+ expect ( scriptContent ) . toContain ( ".push(arguments)" ) ;
174+ } ) ;
175+
176+ it ( "includes gtag js call with new Date in the init script" , ( ) => {
177+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" /> ) ;
178+
179+ const initScript = screen . getByTestId ( "_next-ga-init" ) ;
180+ const scriptContent = initScript . innerHTML ;
181+
182+ expect ( scriptContent ) . toContain ( "gtag('js', new Date())" ) ;
183+ } ) ;
184+
185+ it ( "handles nonce being undefined" , ( ) => {
186+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" nonce = { undefined } /> ) ;
187+
188+ const initScript = screen . getByTestId ( "_next-ga-init" ) ;
189+ const mainScript = screen . getByTestId ( "_next-ga" ) ;
190+
191+ expect ( initScript ) . toBeInTheDocument ( ) ;
192+ expect ( mainScript ) . toBeInTheDocument ( ) ;
193+ } ) ;
194+
195+ it ( "renders correctly with all optional props" , ( ) => {
196+ render (
197+ < GoogleAnalyticsWorkaround
198+ gaId = "G-ALL-PROPS"
199+ dataLayerName = "myLayer"
200+ nonce = "my-nonce"
201+ debugMode = { true }
202+ /> ,
203+ ) ;
204+
205+ const initScript = screen . getByTestId ( "_next-ga-init" ) ;
206+ const mainScript = screen . getByTestId ( "_next-ga" ) ;
207+ const scriptContent = initScript . innerHTML ;
208+
209+ expect ( initScript ) . toHaveAttribute ( "data-nonce" , "my-nonce" ) ;
210+ expect ( mainScript ) . toHaveAttribute ( "data-nonce" , "my-nonce" ) ;
211+ expect ( scriptContent ) . toContain ( "window['myLayer']" ) ;
212+ expect ( scriptContent ) . toContain ( "'debug_mode': true" ) ;
213+ expect ( scriptContent ) . toContain ( "gtag('config', 'G-ALL-PROPS'" ) ;
214+ } ) ;
156215} ) ;
157216
158217describe ( "sendGAEvent" , ( ) => {
159218 let consoleWarnSpy : jest . SpyInstance ;
219+ let originalEnv : string | undefined ;
160220
161221 beforeEach ( ( ) => {
162222 consoleWarnSpy = jest . spyOn ( console , "warn" ) . mockImplementation ( ) ;
223+ originalEnv = process . env . NODE_ENV ;
163224 } ) ;
164225
165226 afterEach ( ( ) => {
166227 consoleWarnSpy . mockRestore ( ) ;
228+ process . env . NODE_ENV = originalEnv ;
167229 } ) ;
168230
169231 it ( "returns early in test environment without calling gtag" , ( ) => {
170- const originalEnv = process . env . NODE_ENV ;
171232 process . env . NODE_ENV = "test" ;
172233
173234 sendGAEvent ( "event" , "test_event" , { test : "data" } ) ;
174235
175236 expect ( consoleWarnSpy ) . not . toHaveBeenCalled ( ) ;
237+ } ) ;
176238
177- process . env . NODE_ENV = originalEnv ;
239+ it ( "warns when dataLayer does not exist on window" , ( ) => {
240+ process . env . NODE_ENV = "production" ;
241+
242+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" /> ) ;
243+
244+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
245+ delete ( window as any ) . dataLayer ;
246+
247+ sendGAEvent ( "event" , "click_event" , { button : "submit" } ) ;
248+
249+ expect ( consoleWarnSpy ) . toHaveBeenCalledWith (
250+ "@next/third-parties: GA dataLayer dataLayer does not exist" ,
251+ ) ;
252+ } ) ;
253+
254+ it ( "calls window.gtag when dataLayer exists" , ( ) => {
255+ process . env . NODE_ENV = "production" ;
256+ const mockGtag = jest . fn ( ) ;
257+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
258+ ( window as any ) . gtag = mockGtag ;
259+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
260+ ( window as any ) . dataLayer = [ ] ;
261+
262+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" /> ) ;
263+
264+ sendGAEvent ( "event" , "conversion" , { value : 100 , currency : "USD" } ) ;
265+
266+ expect ( mockGtag ) . toHaveBeenCalledWith ( "event" , "conversion" , {
267+ value : 100 ,
268+ currency : "USD" ,
269+ } ) ;
270+
271+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
272+ delete ( window as any ) . gtag ;
273+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
274+ delete ( window as any ) . dataLayer ;
275+ } ) ;
276+
277+ it ( "calls gtag with different event names and arguments" , ( ) => {
278+ process . env . NODE_ENV = "production" ;
279+ const mockGtag = jest . fn ( ) ;
280+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
281+ ( window as any ) . gtag = mockGtag ;
282+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
283+ ( window as any ) . dataLayer = [ ] ;
284+
285+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" /> ) ;
286+
287+ sendGAEvent ( "event" , "page_view" , { page : "/home" } ) ;
288+
289+ expect ( mockGtag ) . toHaveBeenCalledWith ( "event" , "page_view" , {
290+ page : "/home" ,
291+ } ) ;
292+
293+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
294+ delete ( window as any ) . gtag ;
295+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
296+ delete ( window as any ) . dataLayer ;
297+ } ) ;
298+
299+ it ( "handles empty event arguments" , ( ) => {
300+ process . env . NODE_ENV = "production" ;
301+ const mockGtag = jest . fn ( ) ;
302+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
303+ ( window as any ) . gtag = mockGtag ;
304+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
305+ ( window as any ) . dataLayer = [ ] ;
306+
307+ render ( < GoogleAnalyticsWorkaround gaId = "G-TEST123" /> ) ;
308+
309+ sendGAEvent ( "event" , "simple_event" , { } ) ;
310+
311+ expect ( mockGtag ) . toHaveBeenCalledWith ( "event" , "simple_event" , { } ) ;
312+
313+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
314+ delete ( window as any ) . gtag ;
315+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
316+ delete ( window as any ) . dataLayer ;
178317 } ) ;
179318} ) ;
0 commit comments