This is an automated email from the ASF dual-hosted git repository. jli pushed a commit to branch fix-app-prefix-export in repository https://gitbox.apache.org/repos/asf/superset.git
commit a6239a3930893d0d0d1ff6311b85cc303a714958 Author: Joe Li <[email protected]> AuthorDate: Thu Dec 18 22:17:17 2025 -0800 test(export): add failing tests for double-prefix bug in handleResourceExport SupersetClient.getUrl() already adds the appRoot prefix when building URLs. The current code uses ensureAppRoot() which pre-applies the prefix, causing double-prefixed URLs like /app/prefix/app/prefix/api/v1/... These tests verify the endpoint passed to SupersetClient.get should NOT include the app prefix. They intentionally fail until the fix is applied. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> --- superset-frontend/src/utils/export.test.ts | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/superset-frontend/src/utils/export.test.ts b/superset-frontend/src/utils/export.test.ts index c6900d5362..88aaa06b39 100644 --- a/superset-frontend/src/utils/export.test.ts +++ b/superset-frontend/src/utils/export.test.ts @@ -396,3 +396,42 @@ test('handles export with empty IDs array', async () => { }), ); }); + +// Test to prevent double-prefix bug: SupersetClient.getUrl() already adds +// the appRoot prefix, so handleResourceExport should NOT pre-apply it. +// If we use ensureAppRoot() in export.ts, SupersetClient.getUrl() adds the +// prefix again, resulting in double-prefixed URLs like /app/app/api/v1/... +describe('double-prefix prevention', () => { + // Import the mocked ensureAppRoot to control its behavior per test + const { ensureAppRoot } = jest.requireMock('./pathUtils'); + + const prefixTestCases = [ + { name: 'subdirectory prefix', appRoot: '/superset', resource: 'dashboard', ids: [1] }, + { name: 'nested prefix', appRoot: '/my-app/superset', resource: 'dataset', ids: [1, 2] }, + ]; + + test.each(prefixTestCases)( + 'endpoint should not include app prefix: $name', + async ({ appRoot, resource, ids }) => { + // Simulate real ensureAppRoot behavior: prepend the appRoot + (ensureAppRoot as jest.Mock).mockImplementation( + (path: string) => `${appRoot}${path}`, + ); + + const doneMock = jest.fn(); + await handleResourceExport(resource, ids, doneMock); + + // The endpoint passed to SupersetClient.get should NOT have the appRoot prefix + // because SupersetClient.getUrl() adds it when building the full URL. + const expectedEndpoint = `/api/v1/${resource}/export/?q=!(${ids.join(',')})`; + + // Explicitly verify no prefix in endpoint - this will fail if ensureAppRoot is used + const callArgs = (SupersetClient.get as jest.Mock).mock.calls.slice(-1)[0][0]; + expect(callArgs.endpoint).not.toContain(appRoot); + expect(callArgs.endpoint).toBe(expectedEndpoint); + + // Reset mock for next test + (ensureAppRoot as jest.Mock).mockImplementation((path: string) => path); + }, + ); +});
