Scopes: Don't use redirect if you're on an active scope navigation (#115149)
* Don't use redirectUrl if we are on an active scope navigation * Remove superflous test
This commit is contained in:
@@ -8,6 +8,7 @@ test.use({
|
||||
scopeFilters: true,
|
||||
groupByVariable: true,
|
||||
reloadDashboardsOnParamsChange: true,
|
||||
useScopesNavigationEndpoint: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -61,31 +62,6 @@ test.describe('Scope Redirect Functionality', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('should fall back to scope navigation when no redirectUrl', async ({ page, gotoDashboardPage }) => {
|
||||
const scopes = testScopesWithRedirect();
|
||||
|
||||
await test.step('Navigate to dashboard and open scopes selector', async () => {
|
||||
await gotoDashboardPage({ uid: 'cuj-dashboard-1' });
|
||||
await openScopesSelector(page, scopes);
|
||||
});
|
||||
|
||||
await test.step('Select scope without redirectUrl', async () => {
|
||||
// Select the scope without redirectUrl directly
|
||||
await selectScope(page, 'sn-redirect-fallback', scopes[1]);
|
||||
});
|
||||
|
||||
await test.step('Apply scopes and verify fallback behavior', async () => {
|
||||
await applyScopes(page, [scopes[1]]);
|
||||
|
||||
// Should stay on current dashboard since no redirectUrl is provided
|
||||
// The scope navigation fallback should not redirect (as per existing behavior)
|
||||
await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/);
|
||||
|
||||
// Verify the scope was applied
|
||||
await expect(page).toHaveURL(/scopes=scope-sn-redirect-fallback/);
|
||||
});
|
||||
});
|
||||
|
||||
test('should not redirect when reloading page on dashboard not in dashboard list', async ({
|
||||
page,
|
||||
gotoDashboardPage,
|
||||
@@ -171,4 +147,47 @@ test.describe('Scope Redirect Functionality', () => {
|
||||
await expect(page).not.toHaveURL(/scopes=/);
|
||||
});
|
||||
});
|
||||
|
||||
test('should not redirect to redirectPath when on active scope navigation', async ({ page, gotoDashboardPage }) => {
|
||||
const scopes = testScopesWithRedirect();
|
||||
|
||||
await test.step('Set up scope navigation to dashboard-1', async () => {
|
||||
// First, apply a scope that creates scope navigation to dashboard-1 (without redirectPath)
|
||||
await gotoDashboardPage({ uid: 'cuj-dashboard-1' });
|
||||
await openScopesSelector(page, scopes);
|
||||
await selectScope(page, 'sn-redirect-setup', scopes[2]);
|
||||
await applyScopes(page, [scopes[2]]);
|
||||
|
||||
// Verify we're on dashboard-1 with the scope applied
|
||||
await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/);
|
||||
await expect(page).toHaveURL(/scopes=scope-sn-redirect-setup/);
|
||||
});
|
||||
|
||||
await test.step('Navigate to dashboard-1 to be on active scope navigation', async () => {
|
||||
// Navigate to dashboard-1 which is now a scope navigation target
|
||||
await gotoDashboardPage({
|
||||
uid: 'cuj-dashboard-1',
|
||||
queryParams: new URLSearchParams({ scopes: 'scope-sn-redirect-setup' }),
|
||||
});
|
||||
|
||||
// Verify we're on dashboard-1
|
||||
await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/);
|
||||
});
|
||||
|
||||
await test.step('Apply scope with redirectPath and verify no redirect', async () => {
|
||||
// Now apply a different scope that has redirectPath
|
||||
// Since we're on an active scope navigation, it should NOT redirect
|
||||
await openScopesSelector(page, scopes);
|
||||
await selectScope(page, 'sn-redirect-with-navigation', scopes[3]);
|
||||
await applyScopes(page, [scopes[3]]);
|
||||
|
||||
// Verify the new scope was applied
|
||||
await expect(page).toHaveURL(/scopes=scope-sn-redirect-with-navigation/);
|
||||
|
||||
// Since we're already on the active scope navigation (dashboard-1),
|
||||
// we should NOT redirect to redirectPath (dashboard-3)
|
||||
await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/);
|
||||
await expect(page).not.toHaveURL(/\/d\/cuj-dashboard-3/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -156,13 +156,18 @@ export async function applyScopes(page: Page, scopes?: TestScope[]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url: string =
|
||||
const dashboardBindingsUrl: string =
|
||||
'**/apis/scope.grafana.app/v0alpha1/namespaces/*/find/scope_dashboard_bindings?' +
|
||||
scopes.map((scope) => `scope=scope-${scope.name}`).join('&');
|
||||
|
||||
const scopeNavigationsUrl: string =
|
||||
'**/apis/scope.grafana.app/v0alpha1/namespaces/*/find/scope_navigations?' +
|
||||
scopes.map((scope) => `scope=scope-${scope.name}`).join('&');
|
||||
|
||||
const groups: string[] = ['Most relevant', 'Dashboards', 'Something else', ''];
|
||||
|
||||
await page.route(url, async (route) => {
|
||||
// Mock scope_dashboard_bindings endpoint
|
||||
await page.route(dashboardBindingsUrl, async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
@@ -215,7 +220,52 @@ export async function applyScopes(page: Page, scopes?: TestScope[]) {
|
||||
});
|
||||
});
|
||||
|
||||
const responsePromise = page.waitForResponse((response) => response.url().includes(`/find/scope_dashboard_bindings`));
|
||||
// Mock scope_navigations endpoint
|
||||
await page.route(scopeNavigationsUrl, async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({
|
||||
apiVersion: 'scope.grafana.app/v0alpha1',
|
||||
items: scopes.flatMap((scope) => {
|
||||
const navigations: Array<{
|
||||
kind: string;
|
||||
apiVersion: string;
|
||||
metadata: { name: string; resourceVersion: string; creationTimestamp: string };
|
||||
spec: { url: string; scope: string };
|
||||
status: { title: string };
|
||||
}> = [];
|
||||
|
||||
// Create a scope navigation if dashboardUid is provided
|
||||
if (scope.dashboardUid && scope.addLinks) {
|
||||
navigations.push({
|
||||
kind: 'ScopeNavigation',
|
||||
apiVersion: 'scope.grafana.app/v0alpha1',
|
||||
metadata: {
|
||||
name: `scope-${scope.name}-nav`,
|
||||
resourceVersion: '1',
|
||||
creationTimestamp: 'stamp',
|
||||
},
|
||||
spec: {
|
||||
url: `/d/${scope.dashboardUid}`,
|
||||
scope: `scope-${scope.name}`,
|
||||
},
|
||||
status: {
|
||||
title: scope.dashboardTitle ?? scope.title,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return navigations;
|
||||
}),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
const responsePromise = page.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes(`/find/scope_dashboard_bindings`) || response.url().includes(`/find/scope_navigations`)
|
||||
);
|
||||
const scopeRequestPromises: Array<Promise<Response>> = [];
|
||||
|
||||
for (const scope of scopes) {
|
||||
|
||||
@@ -124,5 +124,23 @@ export const testScopesWithRedirect = (): TestScope[] => {
|
||||
dashboardTitle: 'CUJ Dashboard 2',
|
||||
addLinks: true,
|
||||
},
|
||||
{
|
||||
name: 'sn-redirect-setup',
|
||||
title: 'Setup Navigation',
|
||||
// No redirectPath - used to set up scope navigation to dashboard-1
|
||||
filters: [{ key: 'namespace', operator: 'equals', value: 'setup-nav' }],
|
||||
dashboardUid: 'cuj-dashboard-1', // Creates scope navigation to this dashboard
|
||||
dashboardTitle: 'CUJ Dashboard 1',
|
||||
addLinks: true,
|
||||
},
|
||||
{
|
||||
name: 'sn-redirect-with-navigation',
|
||||
title: 'Redirect With Navigation',
|
||||
redirectPath: '/d/cuj-dashboard-3', // Redirect target
|
||||
filters: [{ key: 'namespace', operator: 'equals', value: 'redirect-with-nav' }],
|
||||
dashboardUid: 'cuj-dashboard-1', // Creates scope navigation to this dashboard
|
||||
dashboardTitle: 'CUJ Dashboard 1',
|
||||
addLinks: true,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user