diff --git a/projects/design-angular-kit/src/lib/components/navigation/navscroll/navscroll.component.spec.ts b/projects/design-angular-kit/src/lib/components/navigation/navscroll/navscroll.component.spec.ts new file mode 100644 index 00000000..d2adf72c --- /dev/null +++ b/projects/design-angular-kit/src/lib/components/navigation/navscroll/navscroll.component.spec.ts @@ -0,0 +1,78 @@ +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { ViewportScroller } from '@angular/common'; +import { RouterTestingModule } from '@angular/router/testing'; +import { TranslateModule } from '@ngx-translate/core'; + +import { ItNavscrollComponent } from './navscroll.component'; +import { NavscrollItem } from './navscroll.model'; + +function makeItems(): NavscrollItem[] { + return [ + { title: 'Section One', href: 'section-1', text: 'Content one', childs: [] }, + { title: 'Section Two', href: 'section-2', text: 'Content two', childs: [] }, + { title: 'Section Three', href: 'section-3', text: 'Content three', childs: [] }, + ]; +} + +describe('ItNavscrollComponent', () => { + let fixture: ComponentFixture; + let component: ItNavscrollComponent; + let scroller: ViewportScroller; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ItNavscrollComponent, RouterTestingModule, TranslateModule.forRoot()], + }).compileComponents(); + + scroller = TestBed.inject(ViewportScroller); + fixture = TestBed.createComponent(ItNavscrollComponent); + component = fixture.componentInstance; + }); + + it('should create', () => { + component.items = makeItems(); + fixture.detectChanges(); + expect(component).toBeTruthy(); + }); + + it('should NOT auto-scroll to first section on initial load', fakeAsync(() => { + const scrollSpy = spyOn(scroller, 'scrollToAnchor'); + component.items = makeItems(); + fixture.detectChanges(); + tick(100); + + // The programmatic init selection must NOT trigger scrollToAnchor + expect(scrollSpy).not.toHaveBeenCalled(); + })); + + it('should render all section headings', () => { + component.items = makeItems(); + fixture.detectChanges(); + + const el: HTMLElement = fixture.nativeElement; + const headings = el.querySelectorAll('.it-page-section'); + expect(headings.length).toBe(3); + expect(headings[0].textContent?.trim()).toBe('Section One'); + expect(headings[1].textContent?.trim()).toBe('Section Two'); + expect(headings[2].textContent?.trim()).toBe('Section Three'); + }); + + it('should display the header text', () => { + component.items = makeItems(); + component.header = 'Navigation'; + fixture.detectChanges(); + + const el: HTMLElement = fixture.nativeElement; + const h3 = el.querySelector('h3'); + expect(h3?.textContent?.trim()).toBe('Navigation'); + }); + + it('should render nav links for each item', () => { + component.items = makeItems(); + fixture.detectChanges(); + + const el: HTMLElement = fixture.nativeElement; + const links = el.querySelectorAll('.nav-link'); + expect(links.length).toBe(3); + }); +}); diff --git a/projects/design-angular-kit/src/lib/components/navigation/navscroll/navscroll.component.ts b/projects/design-angular-kit/src/lib/components/navigation/navscroll/navscroll.component.ts index b9cbf6b0..8f89750d 100644 --- a/projects/design-angular-kit/src/lib/components/navigation/navscroll/navscroll.component.ts +++ b/projects/design-angular-kit/src/lib/components/navigation/navscroll/navscroll.component.ts @@ -14,7 +14,7 @@ import { import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { RouterLink, RouterLinkActive, RouterLinkWithHref } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; -import { delay, filter, map, tap, withLatestFrom } from 'rxjs'; +import { delay, filter, map, skip, tap, withLatestFrom } from 'rxjs'; import { ItNavscrollListItemsComponent } from './navscroll-list-items.component'; import { NavscrollItem } from './navscroll.model'; import { NavscrollStore } from './navscroll.store'; @@ -128,6 +128,9 @@ export class ItNavscrollComponent implements OnInit { takeUntilDestroyed(this.#destroyRef), filter(selected => Boolean(selected)), map(v => v as NavscrollItem), + // Skip the programmatic selection from store.init() so the page + // does not scroll to the first section on initial load (#597). + skip(1), delay(0), //WA tap({ next: ({ href }) => {