/* eslint-disable @typescript-eslint/no-non-null-assertion,@typescript-eslint/ban-ts-comment */ /* * Copyright (C) 2020 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ import { APP_BASE_HREF, CommonModule, Location, LocationStrategy, PathLocationStrategy, } from '@angular/common'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {FormsModule} from '@angular/forms'; import { ChildrenOutletContexts, RouterModule, UrlSerializer, } from '@angular/router'; import {IonicModule} from '@ionic/angular'; import {TranslateModule} from '@ngx-translate/core'; import {SCFacet, SCThingType} from '@openstapps/core'; import {ContextMenuComponent} from './context-menu.component'; import {SettingsModule} from '../../settings/settings.module'; import {ContextMenuService} from './context-menu.service'; import {FilterContext, SortContext} from './context-type'; describe('ContextMenuComponent', async () => { let fixture: ComponentFixture; let instance: ContextMenuComponent; beforeEach(() => { TestBed.configureTestingModule({ declarations: [ContextMenuComponent], providers: [ ChildrenOutletContexts, Location, UrlSerializer, ContextMenuService, {provide: LocationStrategy, useClass: PathLocationStrategy}, {provide: APP_BASE_HREF, useValue: '/'}, ], imports: [ FormsModule, IonicModule.forRoot(), TranslateModule.forRoot(), CommonModule, SettingsModule, RouterModule.forRoot([], {relativeLinkResolution: 'legacy'}), ], }).compileComponents(); fixture = TestBed.createComponent(ContextMenuComponent); instance = fixture.componentInstance; }); it('should show items in sort context', () => { instance.sortOption = getSortContextType(); fixture.detectChanges(); const sort: HTMLElement = fixture.debugElement.nativeElement.querySelector('.context-sort'); const sortItem = sort.querySelector('.sort-item'); expect(sortItem!.querySelector('ion-label')?.textContent).toContain( 'relevance', ); }); it('should show items in filter context', () => { instance.filterOption = getFilterContextType(); fixture.detectChanges(); const filter: HTMLElement = fixture.debugElement.nativeElement.querySelector('.context-filter'); const filterItem = filter.querySelector('.filter-group'); expect(filterItem!.querySelector('ion-list-header')!.textContent).toContain( 'Type', ); }); it('should set sort context value and reverse on click', () => { instance.sortOption = getSortContextType(); fixture.detectChanges(); const sort: HTMLElement = fixture.debugElement.nativeElement.querySelector('.context-sort'); // @ts-ignore const sortItem: HTMLElement = sort.querySelectorAll('.sort-item')[1]; sortItem!.click(); expect(instance.sortOption.value).toEqual('name'); expect(instance.sortOption.reversed).toBe(false); // click again for reverse sortItem!.click(); expect(instance.sortOption.reversed).toBe(true); }); it('should show all filterable facets', () => { // get set facets with non empty buckets const facets: SCFacet[] = getFilterContextType().options; instance.filterOption = getFilterContextType(); fixture.detectChanges(); // get filter context div const filter: HTMLElement = fixture.debugElement.nativeElement.querySelector('.context-filter'); // get all filter groups that represent a facet const filterGroups = filter.querySelectorAll('.filter-group'); expect(filterGroups.length).toEqual(facets.length); for (const facet of facets) { let filterGroup; // get filter option for facets field // eslint-disable-next-line unicorn/no-array-for-each filterGroups.forEach(element => { if ( element .querySelector('ion-list-header')! .textContent!.toString() .toLowerCase() .includes(facet.field) ) { filterGroup = element; return; } }); expect(filterGroup).toBeDefined(); // @ts-ignore const filterItems = filterGroup.querySelectorAll('.filter-item-label'); if (filterItems.length !== facet.buckets.length) { console.log(JSON.stringify(facet)); } expect(filterItems.length).toEqual(facet.buckets.length); // check all buckets are shown for (const bucket of facet.buckets) { let filterItem; for (let i = 0; i < filterItems.length; i++) { if ( filterItems .item(i) .textContent!.toString() .toLowerCase() .indexOf(bucket.key.toLowerCase()) > 0 ) { filterItem = filterItems.item(i); break; } } expect(filterItem).toBeDefined(); } } }); it('should reset filter', () => { instance.filterOption = getFilterContextType(); instance.filterOption.options = [ { field: 'type', buckets: [{count: 10, key: 'date series', checked: true}], }, ]; fixture.detectChanges(); // click reset button const resetButton: HTMLElement = fixture.debugElement.nativeElement.querySelector('.resetFilterButton'); resetButton.click(); expect(instance.filterOption.options[0].buckets[0].checked).toEqual(false); }); }); /** * */ function getSortContextType(): SortContext { return { name: 'sort', reversed: false, value: 'relevance', values: [ { reversible: false, value: 'relevance', }, { reversible: true, value: 'name', }, { reversible: true, value: 'date', }, { reversible: true, value: 'type', }, ], }; } /** * */ function getFilterContextType(): FilterContext { return { name: 'filter', compact: false, options: facetsMock .filter(facet => facet.buckets.length > 0) .map(facet => { return { buckets: facet.buckets.map(bucket => { return { count: bucket.count, key: bucket.key, checked: false, }; }), compact: false, field: facet.field, onlyOnType: facet.onlyOnType, }; }), }; } const facetsMock: SCFacet[] = [ { buckets: [ { count: 60, key: 'academic event', }, { count: 160, key: 'message', }, { count: 151, key: 'date series', }, { count: 106, key: 'dish', }, { count: 20, key: 'building', }, ], field: 'type', }, { buckets: [ { count: 12, key: 'Max Mustermann', }, { count: 2, key: 'Foo Bar', }, ], field: 'performers', onlyOnType: SCThingType.AcademicEvent, }, { buckets: [ { count: 5, key: 'colloquium', }, { count: 15, key: 'course', }, ], field: 'categories', onlyOnType: SCThingType.AcademicEvent, }, { buckets: [ { count: 5, key: 'employees', }, { count: 15, key: 'students', }, ], field: 'audiences', onlyOnType: SCThingType.Message, }, ];