Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-ng/display/src/lib/services/data-model.service.spec.ts is written in an unsupported language. File is not indexed.

0001 /**
0002  * Which event is selected right after a load.
0003  *
0004  * `currentEntry` is a linkedSignal that follows `entries`, so it has already
0005  * settled on the first event by the time the loader publishes them. Adopting
0006  * events must therefore SELECT the first one, not step to the "next" - with one
0007  * event that wrapped around and looked correct, with several it showed the
0008  * second event while the painter drew the first.
0009  */
0010 
0011 import { TestBed } from '@angular/core/testing';
0012 import { provideHttpClient } from '@angular/common/http';
0013 import { afterEach, describe, expect, it, beforeEach, vi } from 'vitest';
0014 import { ServerConfigService } from '@dexvis/app-features';
0015 import { DataExchange, Event } from '@dexvis/firebird-core';
0016 import { DataModelService } from './data-model.service';
0017 
0018 function dexDocument(eventIds: string[]): unknown {
0019   return {
0020     type: 'firebird-dex-json',
0021     version: '1.0',
0022     events: eventIds.map(id => ({ id, pieces: [] })),
0023   };
0024 }
0025 
0026 describe('DataModelService entry selection', () => {
0027   let service: DataModelService;
0028 
0029   beforeEach(() => {
0030     TestBed.resetTestingModule();
0031     TestBed.configureTestingModule({ providers: [provideHttpClient()] });
0032     service = TestBed.inject(DataModelService);
0033   });
0034 
0035   it('selects the first event of a multi-event document', () => {
0036     const data = service.loadDexObject(dexDocument(['0', '1', '2']));
0037     expect(data).toBeInstanceOf(DataExchange);
0038     expect(service.entries().length).toBe(3);
0039     expect(service.currentEntry()?.id).toBe('0');
0040   });
0041 
0042   it('selects the only event of a single-event document', () => {
0043     service.loadDexObject(dexDocument(['7']));
0044     expect(service.currentEntry()?.id).toBe('7');
0045   });
0046 
0047   it('rejects an object that is not DEX', () => {
0048     expect(service.loadDexObject({ type: 'something-else' })).toBeNull();
0049   });
0050 
0051   it('still steps forward when asked to', () => {
0052     service.loadDexObject(dexDocument(['0', '1', '2']));
0053     service.setNextEntry();
0054     expect(service.currentEntry()?.id).toBe('1');
0055     service.setNextEntry();
0056     service.setNextEntry();
0057     // wraps around
0058     expect((service.currentEntry() as Event).id).toBe('0');
0059   });
0060 });
0061 
0062 describe('DataModelService server conversion', () => {
0063   let service: DataModelService;
0064   const requested: string[] = [];
0065 
0066   beforeEach(() => {
0067     requested.length = 0;
0068     TestBed.resetTestingModule();
0069     TestBed.configureTestingModule({ providers: [provideHttpClient()] });
0070     // Served by pyrobird: the convert endpoint lives at the API base URL
0071     TestBed.inject(ServerConfigService).setUnitTestConfig({ servedByPyrobird: true, apiBaseUrl: 'http://localhost:5454' });
0072     service = TestBed.inject(DataModelService);
0073   });
0074 
0075   afterEach(() => vi.unstubAllGlobals());
0076 
0077   it("asks the server to detect the data model ('auto'), so EDM4hep files convert too", async () => {
0078     vi.stubGlobal('fetch', async (input: string) => {
0079       requested.push(String(input));
0080       return new Response(JSON.stringify(dexDocument(['0', '1'])), { status: 200 });
0081     });
0082     const data = await service.fetchRootConversion('root://host//data/sim.edm4hep.root', '0-1', ['mc_trajectories']);
0083     expect(requested).toEqual([
0084       'http://localhost:5454/api/v1/convert/auto/0-1?f=' +
0085         encodeURIComponent('root://host//data/sim.edm4hep.root') + '&collections=mc_trajectories',
0086     ]);
0087     expect(data.events.map(event => event.id)).toEqual(['0', '1']);
0088     // Fetching does not replace the loaded events; the display adopts them
0089     expect(service.entries()).toEqual([]);
0090   });
0091 
0092   it("rejects with the server's reason for a request with no entry in the file", async () => {
0093     vi.stubGlobal('fetch', async () => new Response(
0094       JSON.stringify({ error: "For entries='50-60': Event 50-60 is out of range: the file holds 2 events (0..1)" }),
0095       { status: 400, statusText: 'BAD REQUEST' }));
0096     await expect(service.fetchRootConversion('root://host//f.root', '50-60'))
0097       .rejects.toThrow(/HTTP 400 BAD REQUEST: For entries='50-60': Event 50-60 is out of range/);
0098   });
0099 
0100   it('rejects an old DEX version with the upgrade command', () => {
0101     expect(() => service.parseDex({ ...dexDocument(['0']) as object, version: '0.04' }, 'old.firebird.json'))
0102       .toThrow(/pyrobird upgrade/);
0103     expect(() => service.parseDex({ type: 'other' }, 'x.json')).toThrow("'x.json' is not a Firebird DEX document");
0104   });
0105 });