1919/**
2020 * External dependencies
2121 */
22- import { waitFor } from '@testing-library/react' ;
22+ import { waitFor , act } from '@testing-library/react' ;
2323
2424/**
2525 * Internal dependencies
@@ -33,6 +33,7 @@ import {
3333 provideUserAuthentication ,
3434 provideModuleRegistrations ,
3535 provideSiteInfo ,
36+ waitForDefaultTimeouts ,
3637} from '../../../../../tests/js/test-utils' ;
3738import { CORE_USER } from '@/js/googlesitekit/datastore/user/constants' ;
3839import { MODULE_SLUG_ANALYTICS_4 } from '@/js/modules/analytics-4/constants' ;
@@ -122,7 +123,29 @@ describe( 'SetupAnalyticsNotice', () => {
122123 ) ;
123124 } ) ;
124125
125- it ( 'dismisses the notice when "Got it" is clicked' , async ( ) => {
126+ it ( 'dismisses the notice when "Maybe later" is clicked' , async ( ) => {
127+ // Create a fresh registry without module registrations to avoid
128+ // async resolver state updates that cause act() warnings.
129+ registry = createTestRegistry ( ) ;
130+ provideSiteInfo ( registry ) ;
131+ provideUserAuthentication ( registry ) ;
132+ provideUserCapabilities ( registry ) ;
133+ provideModules ( registry , [
134+ {
135+ slug : MODULE_SLUG_ANALYTICS_4 ,
136+ active : false ,
137+ connected : false ,
138+ disconnectedAt : false ,
139+ } ,
140+ ] ) ;
141+
142+ // Note: Intentionally not calling `provideModuleRegistrations` here
143+ // to prevent the Analytics 4 store resolver from running.
144+ registry . dispatch ( CORE_USER ) . receiveGetDismissedItems ( [ ] ) ;
145+ registry . dispatch ( CORE_SITE ) . receiveGetEmailReportingSettings ( {
146+ enabled : true ,
147+ } ) ;
148+
126149 fetchMock . getOnce ( fetchGetDismissedItems , { body : [ ] } ) ;
127150 fetchMock . postOnce ( fetchDismissItem , {
128151 body : [ EMAIL_REPORTING_SETUP_ANALYTICS_NOTICE_DISMISSED_ITEM ] ,
@@ -171,4 +194,98 @@ describe( 'SetupAnalyticsNotice', () => {
171194
172195 expect ( container ) . toBeEmptyDOMElement ( ) ;
173196 } ) ;
197+
198+ it ( 'shows spinner and disabled state while the activation is in progress' , async ( ) => {
199+ const moduleActivationEndpoint = RegExp (
200+ 'google-site-kit/v1/core/modules/data/activation'
201+ ) ;
202+
203+ const userAuthenticationEndpoint = RegExp (
204+ '^/google-site-kit/v1/core/user/data/authentication'
205+ ) ;
206+
207+ fetchMock . getOnce ( userAuthenticationEndpoint , {
208+ body : { needsReauthentication : false } ,
209+ } ) ;
210+
211+ // Use a never-resolving promise to keep the activation in progress.
212+ fetchMock . postOnce ( moduleActivationEndpoint , new Promise ( ( ) => { } ) ) ;
213+
214+ const { getByRole } = render ( < SetupAnalyticsNotice /> , {
215+ registry,
216+ } ) ;
217+
218+ const ctaButton = getByRole ( 'button' , {
219+ name : / c o n n e c t a n a l y t i c s / i,
220+ } ) ;
221+
222+ fireEvent . click ( ctaButton ) ;
223+
224+ // Wait for the spinner to appear.
225+ await waitFor ( ( ) => {
226+ expect ( ctaButton ) . toHaveAttribute ( 'disabled' ) ;
227+ } ) ;
228+
229+ // Verify the button contains the spinner (via the CSS class).
230+ expect ( ctaButton ) . toHaveClass (
231+ 'googlesitekit-notice__cta--spinner__running'
232+ ) ;
233+ } ) ;
234+
235+ it ( 'shows "Complete setup" CTA and skips activation when Analytics is active but not connected' , async ( ) => {
236+ // Create a fresh registry with Analytics active but not connected.
237+ registry = createTestRegistry ( ) ;
238+ provideSiteInfo ( registry ) ;
239+ provideUserAuthentication ( registry ) ;
240+ provideUserCapabilities ( registry ) ;
241+ provideModules ( registry , [
242+ {
243+ slug : MODULE_SLUG_ANALYTICS_4 ,
244+ active : true ,
245+ connected : false ,
246+ disconnectedAt : false ,
247+ } ,
248+ ] ) ;
249+ provideModuleRegistrations ( registry ) ;
250+
251+ registry . dispatch ( CORE_USER ) . receiveGetDismissedItems ( [ ] ) ;
252+ registry . dispatch ( CORE_SITE ) . receiveGetEmailReportingSettings ( {
253+ enabled : true ,
254+ } ) ;
255+
256+ const moduleActivationEndpoint = RegExp (
257+ 'google-site-kit/v1/core/modules/data/activation'
258+ ) ;
259+
260+ const { getByRole } = render ( < SetupAnalyticsNotice /> , {
261+ registry,
262+ } ) ;
263+
264+ // Verify the CTA label is "Complete setup".
265+ const ctaButton = getByRole ( 'button' , {
266+ name : / c o m p l e t e s e t u p / i,
267+ } ) ;
268+
269+ expect ( ctaButton ) . toBeInTheDocument ( ) ;
270+
271+ await act ( async ( ) => {
272+ fireEvent . click ( ctaButton ) ;
273+ await waitForDefaultTimeouts ( ) ;
274+ } ) ;
275+
276+ // Verify that the activation endpoint was NOT called.
277+ expect ( fetchMock ) . not . toHaveFetched ( moduleActivationEndpoint ) ;
278+ } ) ;
279+
280+ it ( 'shows external link indicator on the "Learn more" link' , ( ) => {
281+ const { container } = render ( < SetupAnalyticsNotice /> , {
282+ registry,
283+ } ) ;
284+
285+ // Find the link by looking for the external icon SVG.
286+ const externalIcon = container . querySelector (
287+ '.googlesitekit-cta-link svg'
288+ ) ;
289+ expect ( externalIcon ) . toBeInTheDocument ( ) ;
290+ } ) ;
174291} ) ;
0 commit comments