import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NodeSettingField, NodeSettingsDialogService } from '@services/dialogs/node-settings-dialog'; import { NodeSettingsDialogHostComponent } from './node-settings-dialog'; const PARAMETER_GROUP = 'Model parameters'; function fields(): NodeSettingField[] { return [ { key: 'provider', label: 'Provider', type: 'select', options: [{ label: 'p', value: 'p' }], required: true }, { key: 'model', label: 'Model', type: 'select', options: [{ label: 'm', value: 'm' }], required: true }, { key: 'temperature', label: 'Temperature', type: 'number', min: 0, max: 2, group: PARAMETER_GROUP }, { key: 'seed', label: 'Seed', type: 'number', group: PARAMETER_GROUP } ]; } describe('NodeSettingsDialogHostComponent collapsible groups', () => { let fixture: ComponentFixture; let component: NodeSettingsDialogHostComponent; let dialog: NodeSettingsDialogService; async function open(initial: Record = {}) { dialog.open({ title: 'Simulation Settings', fields: fields(), initial }); fixture.detectChanges(); await fixture.whenStable(); fixture.detectChanges(); } beforeEach(async () => { await TestBed.configureTestingModule({ imports: [NodeSettingsDialogHostComponent] }).compileComponents(); fixture = TestBed.createComponent(NodeSettingsDialogHostComponent); component = fixture.componentInstance; dialog = TestBed.inject(NodeSettingsDialogService); }); afterEach(() => TestBed.resetTestingModule()); it('shows the ungrouped fields and keeps the group closed', async () => { // Provider and model are what anyone opening this came for; the parameters are for the runs // where you already know you want them. await open(); expect(component.ungroupedFields().map((field) => field.key)).toEqual(['provider', 'model']); expect(component.fieldGroups().map((group) => group.name)).toEqual([PARAMETER_GROUP]); expect(component.isGroupOpen(PARAMETER_GROUP)).toBe(false); expect(fixture.nativeElement.textContent).toContain(PARAMETER_GROUP); // Closed means the controls are not rendered, not merely hidden. expect(fixture.nativeElement.querySelectorAll('input[type="number"]').length).toBe(0); }); it('opens and closes the group on demand', async () => { await open(); component.toggleGroup(PARAMETER_GROUP); fixture.detectChanges(); expect(component.isGroupOpen(PARAMETER_GROUP)).toBe(true); expect(fixture.nativeElement.querySelectorAll('input[type="number"]').length).toBe(2); component.toggleGroup(PARAMETER_GROUP); fixture.detectChanges(); expect(component.isGroupOpen(PARAMETER_GROUP)).toBe(false); }); it('says how many are set while the group is closed', async () => { // A closed section that is doing something must not look like one that is not. await open({ temperature: 0 }); expect(component.groupSetCount(component.fieldGroups()[0].fields)).toBe(1); expect(fixture.nativeElement.textContent).toContain('1 set'); }); it('counts a set value of zero, which is a real setting', async () => { await open({ temperature: 0, seed: 42 }); expect(component.groupSetCount(component.fieldGroups()[0].fields)).toBe(2); }); it('counts nothing when the group is untouched', async () => { await open(); expect(component.groupSetCount(component.fieldGroups()[0].fields)).toBe(0); expect(fixture.nativeElement.textContent).not.toContain('set'); }); it('reopens a later dialog with the group closed again', async () => { await open(); component.toggleGroup(PARAMETER_GROUP); expect(component.isGroupOpen(PARAMETER_GROUP)).toBe(true); dialog.close(null); await open(); expect(component.isGroupOpen(PARAMETER_GROUP)).toBe(false); }); });