From a335165b8f5f64f9905324a6eba5ec4aaabcc029 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 31 Mar 2023 11:13:39 +0400 Subject: [PATCH] fix(angular): Handle routes with empty path Update function getParameterizedRouteFromSnapshot to handle routes with empty paths. Fixes GH-7681 --- packages/angular/src/tracing.ts | 22 ++++++++++++++++------ packages/angular/test/tracing.test.ts | 26 +++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/packages/angular/src/tracing.ts b/packages/angular/src/tracing.ts index 0d51b2dbfcbc..c200fbc567cb 100644 --- a/packages/angular/src/tracing.ts +++ b/packages/angular/src/tracing.ts @@ -282,14 +282,24 @@ export function TraceMethodDecorator(): MethodDecorator { * child route with its parent to produce the complete parameterized URL of the activated route. * This happens recursively until the last child (i.e. the end of the URL) is reached. * - * @param route the ActivatedRouteSnapshot of which its path and its child's path is concantenated + * @param route the ActivatedRouteSnapshot of which its path and its child's path is concatenated * - * @returns the concatenated parameterzited route string + * @returns the concatenated parameterized route string */ export function getParameterizedRouteFromSnapshot(route?: ActivatedRouteSnapshot | null): string { - const path = route && route.firstChild && route.firstChild.routeConfig && route.firstChild.routeConfig.path; - if (!path) { - return '/'; + const parts: string[] = []; + + let currentRoute = route && route.firstChild; + while (currentRoute) { + const path = currentRoute && currentRoute.routeConfig && currentRoute.routeConfig.path; + if (path === null || path === undefined) { + break; + } + + parts.push(path); + currentRoute = currentRoute.firstChild; } - return `/${path}${getParameterizedRouteFromSnapshot(route && route.firstChild)}`; + + const fullPath = parts.filter(part => part).join('/'); + return fullPath ? `/${fullPath}/` : '/'; } diff --git a/packages/angular/test/tracing.test.ts b/packages/angular/test/tracing.test.ts index 18bc1324f1eb..0afef2771add 100644 --- a/packages/angular/test/tracing.test.ts +++ b/packages/angular/test/tracing.test.ts @@ -55,7 +55,14 @@ describe('Angular Tracing', () => { describe('getParameterizedRouteFromSnapshot', () => { it.each([ - ['returns `/` empty object if the route no children', {}, '/'], + ['returns `/` if the route has no children', {}, '/'], + [ + 'returns `/` if the route has an empty child', + { + firstChild: { routeConfig: { path: '' } }, + }, + '/', + ], [ 'returns the route of a snapshot without children', { @@ -76,6 +83,21 @@ describe('Angular Tracing', () => { }, '/orgs/:orgId/projects/:projId/overview/', ], + [ + 'returns the route of a snapshot without children but with empty paths', + { + firstChild: { + routeConfig: { path: 'users' }, + firstChild: { + routeConfig: { path: '' }, + firstChild: { + routeConfig: { path: ':id' }, + }, + }, + }, + }, + '/users/:id/', + ], ])('%s', (_, routeSnapshot, expectedParams) => { expect(getParameterizedRouteFromSnapshot(routeSnapshot as unknown as ActivatedRouteSnapshot)).toEqual( expectedParams, @@ -345,6 +367,7 @@ describe('Angular Tracing', () => { public ngOnInit() { origNgOnInitMock(); } + public ngAfterViewInit() { origNgAfterViewInitMock(); } @@ -398,6 +421,7 @@ describe('Angular Tracing', () => { public ngOnInit() { origNgOnInitMock(); } + @TraceMethodDecorator() public ngAfterViewInit() { origNgAfterViewInitMock();