Skip to content

Commit 93c098c

Browse files
authored
Merge pull request #10723 from google/fix/#10717-key-metrics-custom-dimensions
Fix custom dimensions in during initial KM setup
2 parents 8dc45b7 + 13bdac6 commit 93c098c

6 files changed

Lines changed: 409 additions & 37 deletions

File tree

assets/js/components/KeyMetrics/FullScreenMetricSelectionApp.js

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@
1919
/**
2020
* WordPress dependencies
2121
*/
22-
import { Fragment, useCallback, useEffect } from '@wordpress/element';
22+
import { Fragment, useEffect } from '@wordpress/element';
2323
import { __ } from '@wordpress/i18n';
2424

2525
/**
2626
* Internal dependencies
2727
*/
2828
import { useSelect, useDispatch } from 'googlesitekit-data';
2929
import { ProgressBar } from 'googlesitekit-components';
30-
import { CORE_LOCATION } from '../../googlesitekit/datastore/location/constants';
3130
import { CORE_SITE } from '../../googlesitekit/datastore/site/constants';
3231
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
3332
import { Cell, Grid, Row } from '../../material-components';
@@ -43,13 +42,8 @@ import {
4342
import { CORE_FORMS } from '../../googlesitekit/datastore/forms/constants';
4443

4544
export default function FullScreenMetricSelectionApp() {
46-
const { navigateTo } = useDispatch( CORE_LOCATION );
4745
const { setValues } = useDispatch( CORE_FORMS );
4846

49-
const mainDashboardURL = useSelect( ( select ) =>
50-
select( CORE_SITE ).getAdminURL( 'googlesitekit-dashboard' )
51-
);
52-
5347
const hasFinishedGettingInputSettings = useSelect( ( select ) => {
5448
// This needs to be called here to check on its resolution,
5549
// as it's called/used by child components of this component,
@@ -63,10 +57,6 @@ export default function FullScreenMetricSelectionApp() {
6357
);
6458
} );
6559

66-
const closePanel = useCallback( () => {
67-
navigateTo( mainDashboardURL );
68-
}, [ navigateTo, mainDashboardURL ] );
69-
7060
const savedViewableMetrics = useSelect( ( select ) => {
7161
const metrics = select( CORE_USER ).getKeyMetrics();
7262

@@ -83,12 +73,6 @@ export default function FullScreenMetricSelectionApp() {
8373
select( CORE_SITE ).isKeyMetricsSetupCompleted()
8474
);
8575

86-
useEffect( () => {
87-
if ( isKeyMetricsSetupCompleted && mainDashboardURL ) {
88-
navigateTo( mainDashboardURL );
89-
}
90-
}, [ mainDashboardURL, navigateTo, isKeyMetricsSetupCompleted ] );
91-
9276
useEffect( () => {
9377
setValues( KEY_METRICS_SELECTION_FORM, {
9478
[ KEY_METRICS_SELECTED ]: savedViewableMetrics,
@@ -156,7 +140,6 @@ export default function FullScreenMetricSelectionApp() {
156140
smSize={ 6 }
157141
>
158142
<PanelContent
159-
closePanel={ closePanel }
160143
savedViewableMetrics={
161144
savedViewableMetrics
162145
}
Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
/**
2+
* Key Metrics FullScreenMetricSelectionApp component tests.
3+
*
4+
* Site Kit by Google, Copyright 2025 Google LLC
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
/**
20+
* Internal dependencies
21+
*/
22+
import FullScreenMetricSelectionApp from './FullScreenMetricSelectionApp';
23+
import { CORE_FORMS } from '../../googlesitekit/datastore/forms/constants';
24+
import {
25+
CORE_USER,
26+
KM_ANALYTICS_PAGES_PER_VISIT,
27+
KM_ANALYTICS_POPULAR_AUTHORS,
28+
KM_ANALYTICS_TOP_CATEGORIES,
29+
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES,
30+
KM_ANALYTICS_VISIT_LENGTH,
31+
KM_ANALYTICS_VISITS_PER_VISITOR,
32+
} from '../../googlesitekit/datastore/user/constants';
33+
import {
34+
EDIT_SCOPE,
35+
FORM_CUSTOM_DIMENSIONS_CREATE,
36+
MODULES_ANALYTICS_4,
37+
} from '../../modules/analytics-4/datastore/constants';
38+
import { ERROR_CODE_MISSING_REQUIRED_SCOPE } from '../../util/errors';
39+
import { KEY_METRICS_WIDGETS } from './key-metrics-widgets';
40+
import { VIEW_CONTEXT_METRIC_SELECTION } from '../../googlesitekit/constants';
41+
import {
42+
act,
43+
createTestRegistry,
44+
fireEvent,
45+
provideKeyMetrics,
46+
provideModules,
47+
provideSiteInfo,
48+
provideUserAuthentication,
49+
provideUserInfo,
50+
render,
51+
waitFor,
52+
} from '../../../../tests/js/test-utils';
53+
import { mockLocation } from '../../../../tests/js/mock-browser-utils';
54+
import { provideKeyMetricsWidgetRegistrations } from './test-utils';
55+
import { withConnected } from '../../googlesitekit/modules/datastore/__fixtures__';
56+
57+
describe( 'FullScreenMetricSelectionApp', () => {
58+
mockLocation();
59+
60+
let registry;
61+
62+
const coreKeyMetricsEndpointRegExp = new RegExp(
63+
'^/google-site-kit/v1/core/user/data/key-metrics'
64+
);
65+
66+
const coreUserInputSettingsExpectedResponse = {
67+
purpose: {
68+
values: [ 'purpose1' ],
69+
scope: 'site',
70+
},
71+
postFrequency: {
72+
values: [ 'daily' ],
73+
scope: 'user',
74+
},
75+
goals: {
76+
values: [ 'goal1', 'goal2' ],
77+
scope: 'user',
78+
},
79+
};
80+
81+
beforeEach( () => {
82+
registry = createTestRegistry();
83+
84+
provideSiteInfo( registry );
85+
provideUserAuthentication( registry );
86+
provideUserInfo( registry, { id: 1 } );
87+
provideModules( registry, withConnected( 'analytics-4' ) );
88+
provideKeyMetrics( registry );
89+
90+
registry.dispatch( CORE_USER ).receiveGetDismissedItems( [] );
91+
registry.dispatch( CORE_USER ).receiveGetDismissedPrompts( [] );
92+
registry.dispatch( CORE_USER ).receiveIsUserInputCompleted( false );
93+
94+
registry
95+
.dispatch( CORE_USER )
96+
.receiveGetUserInputSettings(
97+
coreUserInputSettingsExpectedResponse
98+
);
99+
100+
registry
101+
.dispatch( CORE_USER )
102+
.finishResolution( 'getUserInputSettings', [] );
103+
104+
provideKeyMetricsWidgetRegistrations(
105+
registry,
106+
Object.keys( KEY_METRICS_WIDGETS ).reduce(
107+
( acc, widget ) => ( {
108+
...acc,
109+
[ widget ]: {
110+
modules: [ 'analytics-4' ],
111+
},
112+
} ),
113+
{}
114+
)
115+
);
116+
117+
registry.dispatch( CORE_USER ).receiveCapabilities( {
118+
googlesitekit_manage_options: true,
119+
} );
120+
121+
registry.dispatch( MODULES_ANALYTICS_4 ).receiveGetSettings( {
122+
propertyID: 1234567,
123+
availableCustomDimensions: [],
124+
} );
125+
} );
126+
127+
it( 'should render the component', async () => {
128+
const { getByText, waitForRegistry } = render(
129+
<FullScreenMetricSelectionApp />,
130+
{
131+
registry,
132+
viewContext: VIEW_CONTEXT_METRIC_SELECTION,
133+
}
134+
);
135+
136+
await waitForRegistry();
137+
138+
expect(
139+
getByText(
140+
'Select up to 8 metrics that are most important for your business goals'
141+
)
142+
).toBeInTheDocument();
143+
} );
144+
145+
it( 'should navigate to the dashboard after saving', async () => {
146+
fetchMock.postOnce( coreKeyMetricsEndpointRegExp, {
147+
body: {
148+
widgetSlugs: [
149+
KM_ANALYTICS_PAGES_PER_VISIT,
150+
KM_ANALYTICS_VISIT_LENGTH,
151+
KM_ANALYTICS_VISITS_PER_VISITOR,
152+
],
153+
isWidgetHidden: false,
154+
},
155+
status: 200,
156+
} );
157+
158+
provideKeyMetrics( registry, {
159+
widgetSlugs: [
160+
KM_ANALYTICS_PAGES_PER_VISIT,
161+
KM_ANALYTICS_VISIT_LENGTH,
162+
KM_ANALYTICS_VISITS_PER_VISITOR,
163+
],
164+
} );
165+
166+
const { getByText, waitForRegistry } = render(
167+
<FullScreenMetricSelectionApp />,
168+
{
169+
registry,
170+
viewContext: VIEW_CONTEXT_METRIC_SELECTION,
171+
}
172+
);
173+
174+
await waitForRegistry();
175+
176+
fireEvent.click( getByText( 'Complete setup' ) );
177+
178+
await waitFor( () => {
179+
expect( global.location.assign ).toHaveBeenCalled();
180+
} );
181+
182+
expect( global.location.assign ).toHaveBeenCalledWith(
183+
'http://example.com/wp-admin/admin.php?page=googlesitekit-dashboard'
184+
);
185+
} );
186+
187+
it( 'should set autoSubmit to true after saving if required custom dimensions are missing', async () => {
188+
fetchMock.postOnce( coreKeyMetricsEndpointRegExp, {
189+
body: {
190+
widgetSlugs: [
191+
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES,
192+
KM_ANALYTICS_POPULAR_AUTHORS,
193+
KM_ANALYTICS_TOP_CATEGORIES,
194+
],
195+
isWidgetHidden: false,
196+
},
197+
status: 200,
198+
} );
199+
200+
provideKeyMetrics( registry, {
201+
widgetSlugs: [
202+
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES,
203+
KM_ANALYTICS_POPULAR_AUTHORS,
204+
KM_ANALYTICS_TOP_CATEGORIES,
205+
],
206+
} );
207+
208+
const { getByText, waitForRegistry } = render(
209+
<FullScreenMetricSelectionApp />,
210+
{
211+
registry,
212+
viewContext: VIEW_CONTEXT_METRIC_SELECTION,
213+
}
214+
);
215+
216+
await waitForRegistry();
217+
218+
expect(
219+
registry
220+
.select( CORE_FORMS )
221+
.getValue( FORM_CUSTOM_DIMENSIONS_CREATE, 'autoSubmit' )
222+
).toBeUndefined();
223+
224+
fireEvent.click( getByText( 'Complete setup' ) );
225+
226+
await waitFor( () => {
227+
expect(
228+
registry
229+
.select( CORE_FORMS )
230+
.getValue( FORM_CUSTOM_DIMENSIONS_CREATE, 'autoSubmit' )
231+
).toBe( true );
232+
} );
233+
} );
234+
235+
it( 'should set permission scope error after saving if required custom dimensions and scope are missing', async () => {
236+
provideUserAuthentication( registry, {
237+
unsatisfiedScopes: [ EDIT_SCOPE ],
238+
} );
239+
240+
fetchMock.postOnce( coreKeyMetricsEndpointRegExp, {
241+
body: {
242+
widgetSlugs: [
243+
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES,
244+
KM_ANALYTICS_POPULAR_AUTHORS,
245+
KM_ANALYTICS_TOP_CATEGORIES,
246+
],
247+
isWidgetHidden: false,
248+
},
249+
status: 200,
250+
} );
251+
252+
provideKeyMetrics( registry, {
253+
widgetSlugs: [
254+
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES,
255+
KM_ANALYTICS_POPULAR_AUTHORS,
256+
KM_ANALYTICS_TOP_CATEGORIES,
257+
],
258+
} );
259+
260+
const { getByText, waitForRegistry } = render(
261+
<FullScreenMetricSelectionApp />,
262+
{
263+
registry,
264+
viewContext: VIEW_CONTEXT_METRIC_SELECTION,
265+
}
266+
);
267+
268+
await waitForRegistry();
269+
270+
// eslint-disable-next-line require-await
271+
await act( async () => {
272+
fireEvent.click( getByText( 'Complete setup' ) );
273+
} );
274+
275+
const permissionScopeError = registry
276+
.select( CORE_USER )
277+
.getPermissionScopeError();
278+
279+
expect( permissionScopeError ).toMatchObject( {
280+
code: ERROR_CODE_MISSING_REQUIRED_SCOPE,
281+
data: {
282+
scopes: [ EDIT_SCOPE ],
283+
skipModal: true,
284+
redirectURL:
285+
'http://example.com/wp-admin/admin.php?page=googlesitekit-dashboard&notification=custom_dimensions',
286+
},
287+
} );
288+
} );
289+
290+
it( 'should not navigate to the dashboard after saving if required custom dimensions and scope are missing', async () => {
291+
provideUserAuthentication( registry, {
292+
unsatisfiedScopes: [ EDIT_SCOPE ],
293+
} );
294+
295+
fetchMock.postOnce( coreKeyMetricsEndpointRegExp, {
296+
body: {
297+
widgetSlugs: [
298+
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES,
299+
KM_ANALYTICS_POPULAR_AUTHORS,
300+
KM_ANALYTICS_TOP_CATEGORIES,
301+
],
302+
isWidgetHidden: false,
303+
},
304+
status: 200,
305+
} );
306+
307+
provideKeyMetrics( registry, {
308+
widgetSlugs: [
309+
KM_ANALYTICS_TOP_RECENT_TRENDING_PAGES,
310+
KM_ANALYTICS_POPULAR_AUTHORS,
311+
KM_ANALYTICS_TOP_CATEGORIES,
312+
],
313+
} );
314+
315+
const { getByText, waitForRegistry } = render(
316+
<FullScreenMetricSelectionApp />,
317+
{
318+
registry,
319+
viewContext: VIEW_CONTEXT_METRIC_SELECTION,
320+
}
321+
);
322+
323+
await waitForRegistry();
324+
325+
// eslint-disable-next-line require-await
326+
await act( async () => {
327+
fireEvent.click( getByText( 'Complete setup' ) );
328+
} );
329+
330+
expect( global.location.assign ).not.toHaveBeenCalled();
331+
} );
332+
} );

0 commit comments

Comments
 (0)