Warning, /firebird/packages/firebird-ng/display/src/lib/components/data-selector/manual-tab.component.spec.ts is written in an unsupported language. File is not indexed.
0001 /**
0002 * The manual tab probes every `.root` source to place it in the right field.
0003 * Probes answer in any order; only the latest value of a field is placed.
0004 * Its "Optimize geometry" toggle shows only when a pack registered the rule
0005 * set it selects.
0006 */
0007
0008 import { TestBed } from '@angular/core/testing';
0009 import { provideHttpClient } from '@angular/common/http';
0010 import { beforeEach, describe, expect, it } from 'vitest';
0011 import type { DataSource } from '@dexvis/firebird-core';
0012 import { ConfigService, ServerConfigService } from '@dexvis/app-features';
0013 import {
0014 DataSelectionService,
0015 GEOMETRY_ROOT_FILTER_CONFIG,
0016 ROOT_GEOMETRY_RULES,
0017 type RootGeometryRulesSource,
0018 } from '@dexvis/firebird-ng/api';
0019 import { FileOpenRouterService, type FileRoute } from '../../services/file-open-router.service';
0020 import { ManualTabComponent } from './manual-tab.component';
0021
0022 describe('ManualTabComponent placement', () => {
0023 /** Pending probes by source name; the test answers them in any order. */
0024 let pending: Map<string, (route: FileRoute) => void>;
0025 let tab: ManualTabComponent;
0026 let selection: DataSelectionService;
0027
0028 const answer = async (name: string, kind: 'geometry' | 'events') => {
0029 pending.get(name)!({ kind, loader: {} } as FileRoute);
0030 for (let i = 0; i < 3; i++) await Promise.resolve();
0031 };
0032
0033 beforeEach(() => {
0034 localStorage.clear();
0035 pending = new Map();
0036 TestBed.resetTestingModule();
0037 TestBed.configureTestingModule({
0038 providers: [
0039 provideHttpClient(),
0040 {
0041 provide: FileOpenRouterService,
0042 useValue: {
0043 route: (source: DataSource) => new Promise<FileRoute>(resolve =>
0044 pending.set(typeof source === 'string' ? source : source.name, resolve)),
0045 },
0046 },
0047 ],
0048 });
0049 TestBed.inject(ServerConfigService).setUnitTestConfig({});
0050 selection = TestBed.inject(DataSelectionService);
0051 // The class alone: placement logic needs no template
0052 tab = TestBed.runInInjectionContext(() => new ManualTabComponent());
0053 });
0054
0055 it('places the latest value of a field when an older probe answers last', async () => {
0056 tab.onEventsChange('https://h/old.root');
0057 tab.onEventsChange('https://h/new.root');
0058 await answer('https://h/new.root', 'events');
0059 // The older probe says "geometry"; it must not move or overwrite anything
0060 await answer('https://h/old.root', 'geometry');
0061
0062 expect(tab.events()).toBe('https://h/new.root');
0063 expect(tab.geometry()).not.toBe('https://h/old.root');
0064 expect(tab.note()).toBeNull();
0065 expect(selection.draft().events).toBe('https://h/new.root');
0066 expect(selection.draft().geometry).toBeUndefined();
0067 });
0068
0069 it('still moves a source that the latest probe finds in the wrong field', async () => {
0070 tab.onEventsChange('https://h/detector.root');
0071 await answer('https://h/detector.root', 'geometry');
0072 expect(tab.geometry()).toBe('https://h/detector.root');
0073 expect(tab.note()).toContain('went to the geometry field');
0074 });
0075 });
0076
0077 describe('ManualTabComponent optimize toggle', () => {
0078 /** A tab under the given rule contributions, once their (lazy) data resolved. */
0079 async function createTab(ruleSources: RootGeometryRulesSource[] | null): Promise<ManualTabComponent> {
0080 localStorage.clear();
0081 TestBed.resetTestingModule();
0082 TestBed.configureTestingModule({
0083 providers: [
0084 provideHttpClient(),
0085 ...(ruleSources ? [{ provide: ROOT_GEOMETRY_RULES, useValue: ruleSources }] : []),
0086 ],
0087 });
0088 TestBed.inject(ServerConfigService).setUnitTestConfig({});
0089 const tab = TestBed.runInInjectionContext(() => new ManualTabComponent());
0090 for (let i = 0; i < 3; i++) await Promise.resolve();
0091 return tab;
0092 }
0093
0094 it('stays hidden when no pack registered edit rules', async () => {
0095 expect((await createTab(null)).optimizeRuleSet()).toBeNull();
0096 });
0097
0098 it('stays hidden when the registered rules have no rule set for it', async () => {
0099 const tab = await createTab([{ editRules: { strict: { label: 'Strict', detectors: [] } } }]);
0100 expect(tab.optimizeRuleSet()).toBeNull();
0101 });
0102
0103 it('shows the label of the rule set it selects and switches the config between it and off', async () => {
0104 const tab = await createTab([async () => ({ editRules: { default: { label: 'Remove fine parts', detectors: [] } } })]);
0105 expect(tab.optimizeRuleSet()?.label).toBe('Remove fine parts');
0106
0107 const rootFilter = TestBed.inject(ConfigService).declare(GEOMETRY_ROOT_FILTER_CONFIG);
0108 expect(tab.optimize()).toBe(false);
0109 tab.toggleOptimize();
0110 expect(rootFilter.value).toBe('default');
0111 tab.toggleOptimize();
0112 expect(rootFilter.value).toBe('off');
0113 });
0114 });