diff --git a/adev/src/app/core/constants/pages.ts b/adev/src/app/core/constants/pages.ts index 2f94c4749973..4015e8556668 100644 --- a/adev/src/app/core/constants/pages.ts +++ b/adev/src/app/core/constants/pages.ts @@ -14,6 +14,7 @@ export const DEFAULT_PAGES = { TUTORIALS: 'tutorials', PLAYGROUND: 'playground', UPDATE: 'update-guide', + RANDOM: 'random', } as const; export const PAGE_PREFIX = { @@ -25,4 +26,5 @@ export const PAGE_PREFIX = { REFERENCE: 'reference', TUTORIALS: 'tutorials', UPDATE: 'update-guide', + RANDOM: 'random', } as const; diff --git a/adev/src/app/features/random/random.scss b/adev/src/app/features/random/random.scss new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/adev/src/app/features/random/random.spec.ts b/adev/src/app/features/random/random.spec.ts new file mode 100644 index 000000000000..60f9114c6b8e --- /dev/null +++ b/adev/src/app/features/random/random.spec.ts @@ -0,0 +1,55 @@ +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {Router} from '@angular/router'; +import Random from './random'; +import {SUB_NAVIGATION_DATA} from '../../routing/sub-navigation-data'; + +describe('Random', () => { + let component: Random; + let fixture: ComponentFixture; + let router: Router; + + beforeEach(async () => { + const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']); + + await TestBed.configureTestingModule({ + imports: [Random], + providers: [{provide: Router, useValue: routerSpy}], + }).compileComponents(); + + router = TestBed.inject(Router); + fixture = TestBed.createComponent(Random); + component = fixture.componentInstance; + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should redirect to a random path on init', () => { + fixture.detectChanges(); // Triggers ngOnInit + + expect(router.navigateByUrl).toHaveBeenCalled(); + const call = (router.navigateByUrl as jasmine.Spy).calls.mostRecent(); + const navigatedUrl = call.args[0]; + const options = call.args[1]; + + expect(options.replaceUrl).toBeTrue(); + + // Check if navigatedUrl is one of the possible paths + const allPaths = [ + ...SUB_NAVIGATION_DATA.docs, + ...SUB_NAVIGATION_DATA.reference, + ...SUB_NAVIGATION_DATA.tutorials, + ].flatMap((item) => { + const paths: string[] = []; + const traverse = (node: any) => { + if (node.path && !node.path.startsWith('http')) paths.push(`/${node.path}`); + if (node.children) node.children.forEach(traverse); + }; + traverse(item); + return paths; + }); + + expect(allPaths).toContain(navigatedUrl); + }); +}); diff --git a/adev/src/app/features/random/random.ts b/adev/src/app/features/random/random.ts new file mode 100644 index 000000000000..ad49d4ed45e7 --- /dev/null +++ b/adev/src/app/features/random/random.ts @@ -0,0 +1,32 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {Router} from '@angular/router'; +import {SUB_NAVIGATION_DATA} from '../../routing/sub-navigation-data'; +import {flatNavigationData} from '@angular/docs'; + +@Component({ + selector: 'adev-random', + standalone: true, + template: ``, +}) +export default class Random implements OnInit { + private readonly router = inject(Router); + + ngOnInit(): void { + const allItems = [ + ...flatNavigationData(SUB_NAVIGATION_DATA.docs), + ...flatNavigationData(SUB_NAVIGATION_DATA.reference), + ...flatNavigationData(SUB_NAVIGATION_DATA.tutorials), + ]; + + const paths = allItems + .map((item) => item.path) + .filter((path): path is string => !!path && !path.startsWith('http')); + + if (paths.length > 0) { + const randomPath = paths[Math.floor(Math.random() * paths.length)]; + this.router.navigateByUrl(`/${randomPath}`, {replaceUrl: true}); + } else { + this.router.navigateByUrl('/', {replaceUrl: true}); + } + } +} diff --git a/adev/src/app/routing/routes.ts b/adev/src/app/routing/routes.ts index 5d199e478991..0c09c5acbc4f 100644 --- a/adev/src/app/routing/routes.ts +++ b/adev/src/app/routing/routes.ts @@ -55,9 +55,7 @@ const cliReferencePageRoutes = mapNavigationItemsToRoutes( referenceNavigationItems.filter((r) => r.path?.startsWith(`${PAGE_PREFIX.CLI}/`)), { loadComponent: () => - import( - '../features/references/cli-reference-details-page/cli-reference-details-page.component' - ), + import('../features/references/cli-reference-details-page/cli-reference-details-page.component'), data: commonReferenceRouteData, }, ).map((route) => ({ @@ -148,6 +146,11 @@ export const routes: Route[] = [ loadComponent: () => import('../features/playground/playground.component'), data: {...commonTutorialRouteData, label: 'Playground'}, }, + { + path: PAGE_PREFIX.RANDOM, + loadComponent: () => import('../features/random/random'), + data: {label: 'Random topic'}, + }, ...SUB_NAVIGATION_ROUTES, ...API_REFERENCE_ROUTES, ...FOOTER_ROUTES,