mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-49653 Improving type safety
This commit is contained in:
@@ -41,7 +41,8 @@ export interface FilterCountersQuery {
|
|||||||
status?: string[];
|
status?: string[];
|
||||||
assignee?: string[];
|
assignee?: string[];
|
||||||
sort?: FilterCountersQuerySort;
|
sort?: FilterCountersQuerySort;
|
||||||
[criteria: string]: any;
|
/** Every other criteria of the filter the query was built from. */
|
||||||
|
[criteria: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,13 +62,6 @@ export interface FilterCounterCandidate {
|
|||||||
showCounter?: boolean;
|
showCounter?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Filters of every entity type the counters are resolved for.
|
|
||||||
*/
|
|
||||||
export type FilterCountersFilters = {
|
|
||||||
[entityType in FilterCounterEntityType]: any[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts returned by the batched count request, keyed by entity type and then by the `requestId`
|
* Counts returned by the batched count request, keyed by entity type and then by the `requestId`
|
||||||
* of the query the count was resolved for.
|
* of the query the count was resolved for.
|
||||||
|
|||||||
+7
-7
@@ -33,7 +33,7 @@ import { MatIconHarness } from '@angular/material/icon/testing';
|
|||||||
import { ActivatedRoute, provideRouter, Router } from '@angular/router';
|
import { ActivatedRoute, provideRouter, Router } from '@angular/router';
|
||||||
import { RouterTestingHarness } from '@angular/router/testing';
|
import { RouterTestingHarness } from '@angular/router/testing';
|
||||||
import { FilterCountersCloudService } from '../../../../services/filter-counters-cloud.service';
|
import { FilterCountersCloudService } from '../../../../services/filter-counters-cloud.service';
|
||||||
import { FilterCounterEntityType } from '../../../../models/filter-counters-cloud.model';
|
import { FilterCounterEntityType, FilterCountersResult } from '../../../../models/filter-counters-cloud.model';
|
||||||
import { ProcessFilterCloudModel } from '../../models/process-filter-cloud.model';
|
import { ProcessFilterCloudModel } from '../../models/process-filter-cloud.model';
|
||||||
|
|
||||||
@Component({ selector: 'adf-cloud-dummy', template: '' })
|
@Component({ selector: 'adf-cloud-dummy', template: '' })
|
||||||
@@ -560,12 +560,12 @@ describe('ProcessFiltersCloudComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should keep the counters in sync with the counters stream', fakeAsync(() => {
|
it('should keep the counters in sync with the counters stream', fakeAsync(() => {
|
||||||
const counters$ = new Subject<any>();
|
const counters$ = new Subject<FilterCountersResult>();
|
||||||
getFilterCountersSpy.and.returnValue(counters$.asObservable());
|
getFilterCountersSpy.and.returnValue(counters$.asObservable());
|
||||||
component.appName = 'mock-app-name';
|
component.appName = 'mock-app-name';
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
component.filters = mockProcessFilters.map((filter) => ({ ...filter, showCounter: true })) as any;
|
component.filters = mockProcessFilters.map((filter) => new ProcessFilterCloudModel({ ...filter, showCounter: true }));
|
||||||
|
|
||||||
counters$.next({ counters: { FakeRunningProcesses: 7 }, batched: true });
|
counters$.next({ counters: { FakeRunningProcesses: 7 }, batched: true });
|
||||||
|
|
||||||
@@ -920,12 +920,12 @@ describe('ProcessFiltersCloudComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should keep the counters in sync with the counters stream', fakeAsync(() => {
|
it('should keep the counters in sync with the counters stream', fakeAsync(() => {
|
||||||
const counters$ = new Subject<any>();
|
const counters$ = new Subject<FilterCountersResult>();
|
||||||
getFilterCountersSpy.and.returnValue(counters$.asObservable());
|
getFilterCountersSpy.and.returnValue(counters$.asObservable());
|
||||||
component.appName = 'mock-app-name';
|
component.appName = 'mock-app-name';
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
component.filters = mockProcessFilters.map((filter) => ({ ...filter, showCounter: true })) as any;
|
component.filters = mockProcessFilters.map((filter) => new ProcessFilterCloudModel({ ...filter, showCounter: true }));
|
||||||
|
|
||||||
counters$.next({ counters: { FakeRunningProcesses: 7 }, batched: true });
|
counters$.next({ counters: { FakeRunningProcesses: 7 }, batched: true });
|
||||||
|
|
||||||
@@ -934,12 +934,12 @@ describe('ProcessFiltersCloudComponent', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should resolve the counters one filter at a time when the batched endpoint is not available', fakeAsync(() => {
|
it('should resolve the counters one filter at a time when the batched endpoint is not available', fakeAsync(() => {
|
||||||
const counters$ = new Subject<any>();
|
const counters$ = new Subject<FilterCountersResult>();
|
||||||
getFilterCountersSpy.and.returnValue(counters$.asObservable());
|
getFilterCountersSpy.and.returnValue(counters$.asObservable());
|
||||||
component.appName = 'mock-app-name';
|
component.appName = 'mock-app-name';
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
component.filters = mockProcessFilters.map((filter) => ({ ...filter, showCounter: true })) as any;
|
component.filters = mockProcessFilters.map((filter) => new ProcessFilterCloudModel({ ...filter, showCounter: true }));
|
||||||
getProcessCounterSpy.calls.reset();
|
getProcessCounterSpy.calls.reset();
|
||||||
|
|
||||||
counters$.next({ counters: {}, batched: false });
|
counters$.next({ counters: {}, batched: false });
|
||||||
|
|||||||
+1
-1
@@ -143,7 +143,7 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges {
|
|||||||
this.success.emit(res);
|
this.success.emit(res);
|
||||||
this.loadFilterCounters(appName);
|
this.loadFilterCounters(appName);
|
||||||
},
|
},
|
||||||
error: (err: any) => {
|
error: (err: unknown) => {
|
||||||
this.error.emit(err);
|
this.error.emit(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
|
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||||
import { AppConfigService, NoopAuthModule } from '@alfresco/adf-core';
|
import { AppConfigService, NoopAuthModule } from '@alfresco/adf-core';
|
||||||
import { firstValueFrom, of, Subject, throwError } from 'rxjs';
|
import { firstValueFrom, Observable, of, Subject, throwError } from 'rxjs';
|
||||||
import { ApolloTestingModule } from 'apollo-angular/testing';
|
import { ApolloTestingModule } from 'apollo-angular/testing';
|
||||||
import { FilterCountersCloudService } from './filter-counters-cloud.service';
|
import { FilterCountersCloudService } from './filter-counters-cloud.service';
|
||||||
import { NotificationCloudService } from './notification-cloud.service';
|
import { NotificationCloudService } from './notification-cloud.service';
|
||||||
@@ -27,16 +27,32 @@ import { TaskFilterCloudService } from '../task/task-filters/services/task-filte
|
|||||||
import { ProcessFilterCloudService } from '../process/process-filters/services/process-filter-cloud.service';
|
import { ProcessFilterCloudService } from '../process/process-filters/services/process-filter-cloud.service';
|
||||||
import { TaskFilterCloudModel } from '../task/task-filters/models/filter-cloud.model';
|
import { TaskFilterCloudModel } from '../task/task-filters/models/filter-cloud.model';
|
||||||
import { ProcessFilterCloudModel } from '../process/process-filters/models/process-filter-cloud.model';
|
import { ProcessFilterCloudModel } from '../process/process-filters/models/process-filter-cloud.model';
|
||||||
import { FilterCounterEntityType, FilterCounters } from '../models/filter-counters-cloud.model';
|
import {
|
||||||
|
FilterCounterEntityType,
|
||||||
|
FilterCounters,
|
||||||
|
FilterCountersQuery,
|
||||||
|
FilterCountersRequest,
|
||||||
|
FilterCountersResult
|
||||||
|
} from '../models/filter-counters-cloud.model';
|
||||||
import { TaskCloudEngineEvent } from '../models/engine-event-cloud.model';
|
import { TaskCloudEngineEvent } from '../models/engine-event-cloud.model';
|
||||||
|
import { FetchResult } from '@apollo/client/core';
|
||||||
|
|
||||||
|
type EngineEventsResult = FetchResult<{ engineEvents?: TaskCloudEngineEvent[] }>;
|
||||||
|
|
||||||
|
interface CountEndpoint {
|
||||||
|
post: (url: string, request: FilterCountersRequest) => Observable<FilterCounters>;
|
||||||
|
}
|
||||||
|
|
||||||
describe('FilterCountersCloudService', () => {
|
describe('FilterCountersCloudService', () => {
|
||||||
let service: FilterCountersCloudService;
|
let service: FilterCountersCloudService;
|
||||||
let notificationCloudService: NotificationCloudService;
|
let notificationCloudService: NotificationCloudService;
|
||||||
let appConfigService: AppConfigService;
|
let appConfigService: AppConfigService;
|
||||||
let engineEvents$: Subject<any>;
|
let engineEvents$: Subject<EngineEventsResult>;
|
||||||
let makeGQLQuerySpy: jasmine.Spy;
|
let makeGQLQuerySpy: jasmine.Spy;
|
||||||
let postSpy: jasmine.Spy;
|
let postSpy: jasmine.Spy;
|
||||||
|
/** Payload the batched count endpoint was called with. */
|
||||||
|
const countRequest = (): FilterCountersRequest => postSpy.calls.mostRecent().args[1];
|
||||||
|
const countUrl = (): string => postSpy.calls.mostRecent().args[0];
|
||||||
let getTaskListFiltersSpy: jasmine.Spy;
|
let getTaskListFiltersSpy: jasmine.Spy;
|
||||||
let getProcessFiltersSpy: jasmine.Spy;
|
let getProcessFiltersSpy: jasmine.Spy;
|
||||||
|
|
||||||
@@ -45,8 +61,10 @@ describe('FilterCountersCloudService', () => {
|
|||||||
PROCESS_INSTANCE: { 'running-processes': 5 }
|
PROCESS_INSTANCE: { 'running-processes': 5 }
|
||||||
};
|
};
|
||||||
|
|
||||||
const taskFilter = (filter: any) => new TaskFilterCloudModel({ appName: 'mock-app', sort: 'createdDate', order: 'DESC', ...filter });
|
const taskFilter = (filter: Partial<TaskFilterCloudModel>) =>
|
||||||
const processFilter = (filter: any) => new ProcessFilterCloudModel({ appName: 'mock-app', sort: 'startDate', order: 'DESC', ...filter });
|
new TaskFilterCloudModel({ appName: 'mock-app', sort: 'createdDate', order: 'DESC', ...filter });
|
||||||
|
const processFilter = (filter: Partial<ProcessFilterCloudModel>) =>
|
||||||
|
new ProcessFilterCloudModel({ appName: 'mock-app', sort: 'startDate', order: 'DESC', ...filter });
|
||||||
|
|
||||||
const taskFiltersMock = [
|
const taskFiltersMock = [
|
||||||
taskFilter({ key: 'my-tasks', status: 'ASSIGNED', assignee: 'mock-user', showCounter: true }),
|
taskFilter({ key: 'my-tasks', status: 'ASSIGNED', assignee: 'mock-user', showCounter: true }),
|
||||||
@@ -58,7 +76,8 @@ describe('FilterCountersCloudService', () => {
|
|||||||
processFilter({ key: 'all-processes', status: '', showCounter: false })
|
processFilter({ key: 'all-processes', status: '', showCounter: false })
|
||||||
];
|
];
|
||||||
|
|
||||||
const emitEvent = (eventType = 'TASK_CREATED') => engineEvents$.next({ data: { engineEvents: [{ eventType, entity: {} }] } });
|
const emitEvent = (eventType = 'TASK_CREATED') =>
|
||||||
|
engineEvents$.next({ data: { engineEvents: [{ eventType, entity: {} } as TaskCloudEngineEvent] } });
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@@ -74,9 +93,10 @@ describe('FilterCountersCloudService', () => {
|
|||||||
appConfigService = TestBed.inject(AppConfigService);
|
appConfigService = TestBed.inject(AppConfigService);
|
||||||
appConfigService.config.bpmHost = 'https://fake-bpm-host.com';
|
appConfigService.config.bpmHost = 'https://fake-bpm-host.com';
|
||||||
|
|
||||||
engineEvents$ = new Subject<any>();
|
engineEvents$ = new Subject<EngineEventsResult>();
|
||||||
makeGQLQuerySpy = spyOn(notificationCloudService, 'makeGQLQuery').and.returnValue(engineEvents$.asObservable() as any);
|
makeGQLQuerySpy = spyOn(notificationCloudService, 'makeGQLQuery').and.returnValue(engineEvents$.asObservable());
|
||||||
postSpy = spyOn<any>(service, 'post').and.returnValue(of(countersMock));
|
/* `post` is protected on BaseCloudService, so it is reached through the shape it is spied on. */
|
||||||
|
postSpy = spyOn(service as unknown as CountEndpoint, 'post').and.returnValue(of(countersMock));
|
||||||
getTaskListFiltersSpy = spyOn(TestBed.inject(TaskFilterCloudService), 'getTaskListFilters').and.returnValue(of(taskFiltersMock));
|
getTaskListFiltersSpy = spyOn(TestBed.inject(TaskFilterCloudService), 'getTaskListFilters').and.returnValue(of(taskFiltersMock));
|
||||||
getProcessFiltersSpy = spyOn(TestBed.inject(ProcessFilterCloudService), 'getProcessFilters').and.returnValue(of(processFiltersMock));
|
getProcessFiltersSpy = spyOn(TestBed.inject(ProcessFilterCloudService), 'getProcessFilters').and.returnValue(of(processFiltersMock));
|
||||||
});
|
});
|
||||||
@@ -132,7 +152,7 @@ describe('FilterCountersCloudService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should resolve the counters of both entity types with a single request', () => {
|
it('should resolve the counters of both entity types with a single request', () => {
|
||||||
const results: any[] = [];
|
const results: FilterCountersResult[] = [];
|
||||||
/* Both filter components hold their subscription, so one request resolves the counters of both. */
|
/* Both filter components hold their subscription, so one request resolves the counters of both. */
|
||||||
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe((result) => results.push(result));
|
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe((result) => results.push(result));
|
||||||
service.getFilterCounters('mock-app', FilterCounterEntityType.PROCESS_INSTANCE).subscribe((result) => results.push(result));
|
service.getFilterCounters('mock-app', FilterCounterEntityType.PROCESS_INSTANCE).subscribe((result) => results.push(result));
|
||||||
@@ -147,23 +167,23 @@ describe('FilterCountersCloudService', () => {
|
|||||||
it('should send the queries of both entity types to the batched count endpoint', async () => {
|
it('should send the queries of both entity types to the batched count endpoint', async () => {
|
||||||
await taskCounters();
|
await taskCounters();
|
||||||
|
|
||||||
const [url, body] = postSpy.calls.mostRecent().args;
|
expect(countUrl()).toBe('https://fake-bpm-host.com/mock-app/query/v1/count');
|
||||||
expect(url).toBe('https://fake-bpm-host.com/mock-app/query/v1/count');
|
const body = countRequest();
|
||||||
expect(Object.keys(body)).toEqual([FilterCounterEntityType.TASK, FilterCounterEntityType.PROCESS_INSTANCE]);
|
expect(Object.keys(body)).toEqual([FilterCounterEntityType.TASK, FilterCounterEntityType.PROCESS_INSTANCE]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should identify the query of every filter by the key of the filter', async () => {
|
it('should identify the query of every filter by the key of the filter', async () => {
|
||||||
await taskCounters();
|
await taskCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.TASK.map((query: any) => query.requestId)).toEqual(['my-tasks', 'queued-tasks']);
|
expect(body.TASK.map((query: FilterCountersQuery) => query.requestId)).toEqual(['my-tasks', 'queued-tasks']);
|
||||||
expect(body.PROCESS_INSTANCE.map((query: any) => query.requestId)).toEqual(['running-processes']);
|
expect(body.PROCESS_INSTANCE.map((query: FilterCountersQuery) => query.requestId)).toEqual(['running-processes']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send the criteria of every filter along with its request id', async () => {
|
it('should send the criteria of every filter along with its request id', async () => {
|
||||||
await taskCounters();
|
await taskCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.TASK[0]).toEqual({
|
expect(body.TASK[0]).toEqual({
|
||||||
requestId: 'my-tasks',
|
requestId: 'my-tasks',
|
||||||
status: ['ASSIGNED'],
|
status: ['ASSIGNED'],
|
||||||
@@ -175,8 +195,8 @@ describe('FilterCountersCloudService', () => {
|
|||||||
it('should not send the filters without a counter enabled', async () => {
|
it('should not send the filters without a counter enabled', async () => {
|
||||||
await taskCounters();
|
await taskCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.TASK.map((query: any) => query.requestId)).not.toContain('completed-tasks');
|
expect(body.TASK.map((query: FilterCountersQuery) => query.requestId)).not.toContain('completed-tasks');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send the query of a filter targeting every status', async () => {
|
it('should send the query of a filter targeting every status', async () => {
|
||||||
@@ -184,8 +204,8 @@ describe('FilterCountersCloudService', () => {
|
|||||||
|
|
||||||
await processCounters();
|
await processCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.PROCESS_INSTANCE.map((query: any) => query.requestId)).toEqual(['all-processes']);
|
expect(body.PROCESS_INSTANCE.map((query: FilterCountersQuery) => query.requestId)).toEqual(['all-processes']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should omit an entity type without filters with a counter enabled', async () => {
|
it('should omit an entity type without filters with a counter enabled', async () => {
|
||||||
@@ -193,7 +213,7 @@ describe('FilterCountersCloudService', () => {
|
|||||||
|
|
||||||
await taskCounters();
|
await taskCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.PROCESS_INSTANCE).toBeUndefined();
|
expect(body.PROCESS_INSTANCE).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -204,8 +224,8 @@ describe('FilterCountersCloudService', () => {
|
|||||||
|
|
||||||
await taskCounters();
|
await taskCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.TASK.map((query: any) => query.requestId)).toEqual(['queued-tasks']);
|
expect(body.TASK.map((query: FilterCountersQuery) => query.requestId)).toEqual(['queued-tasks']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should leave out a filter without a key, since it holds no request id', async () => {
|
it('should leave out a filter without a key, since it holds no request id', async () => {
|
||||||
@@ -213,7 +233,7 @@ describe('FilterCountersCloudService', () => {
|
|||||||
|
|
||||||
await processCounters();
|
await processCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.PROCESS_INSTANCE).toBeUndefined();
|
expect(body.PROCESS_INSTANCE).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -222,8 +242,8 @@ describe('FilterCountersCloudService', () => {
|
|||||||
|
|
||||||
await taskCounters();
|
await taskCounters();
|
||||||
|
|
||||||
const [, body] = postSpy.calls.mostRecent().args;
|
const body = countRequest();
|
||||||
expect(body.TASK.map((query: any) => query.requestId)).toEqual(['my-tasks', 'queued-tasks']);
|
expect(body.TASK.map((query: FilterCountersQuery) => query.requestId)).toEqual(['my-tasks', 'queued-tasks']);
|
||||||
expect(body.PROCESS_INSTANCE).toBeUndefined();
|
expect(body.PROCESS_INSTANCE).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -274,7 +294,7 @@ describe('FilterCountersCloudService', () => {
|
|||||||
|
|
||||||
describe('refreshFilterCounters', () => {
|
describe('refreshFilterCounters', () => {
|
||||||
it('should resolve the counters again with a single request', fakeAsync(() => {
|
it('should resolve the counters again with a single request', fakeAsync(() => {
|
||||||
const results: any[] = [];
|
const results: FilterCountersResult[] = [];
|
||||||
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe((result) => results.push(result));
|
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe((result) => results.push(result));
|
||||||
service.getFilterCounters('mock-app', FilterCounterEntityType.PROCESS_INSTANCE).subscribe();
|
service.getFilterCounters('mock-app', FilterCounterEntityType.PROCESS_INSTANCE).subscribe();
|
||||||
|
|
||||||
@@ -363,7 +383,7 @@ describe('FilterCountersCloudService', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should emit the counters resolved for the batch of events', fakeAsync(() => {
|
it('should emit the counters resolved for the batch of events', fakeAsync(() => {
|
||||||
const results: any[] = [];
|
const results: FilterCountersResult[] = [];
|
||||||
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe((result) => results.push(result));
|
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe((result) => results.push(result));
|
||||||
|
|
||||||
postSpy.and.returnValue(of({ TASK: { 'my-tasks': 9 } }));
|
postSpy.and.returnValue(of({ TASK: { 'my-tasks': 9 } }));
|
||||||
@@ -375,7 +395,7 @@ describe('FilterCountersCloudService', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should not subscribe to the engine events when notifications are disabled', fakeAsync(() => {
|
it('should not subscribe to the engine events when notifications are disabled', fakeAsync(() => {
|
||||||
spyOn(appConfigService, 'get').and.callFake((key: string, defaultValue: any) => (key === 'notifications' ? false : defaultValue));
|
appConfigService.config.notifications = false;
|
||||||
|
|
||||||
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe();
|
service.getFilterCounters('mock-app', FilterCounterEntityType.TASK).subscribe();
|
||||||
tick(3000);
|
tick(3000);
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ import {
|
|||||||
FilterCounterCandidate,
|
FilterCounterCandidate,
|
||||||
FilterCounterEntityType,
|
FilterCounterEntityType,
|
||||||
FilterCounters,
|
FilterCounters,
|
||||||
FilterCountersFilters,
|
|
||||||
FilterCountersQuery,
|
FilterCountersQuery,
|
||||||
FilterCountersRequest,
|
FilterCountersRequest,
|
||||||
FilterCountersResult
|
FilterCountersResult
|
||||||
} from '../models/filter-counters-cloud.model';
|
} from '../models/filter-counters-cloud.model';
|
||||||
|
import { FetchResult } from '@apollo/client/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Single subscription covering both the task and the process engine events, so that a batch of
|
* Single subscription covering both the task and the process engine events, so that a batch of
|
||||||
@@ -45,6 +45,15 @@ import {
|
|||||||
*/
|
*/
|
||||||
const BATCHED_COUNTERS_UNAVAILABLE_STATUSES = [404, 501];
|
const BATCHED_COUNTERS_UNAVAILABLE_STATUSES = [404, 501];
|
||||||
|
|
||||||
|
/** Filters of both entity types, to resolve the counters of both filter components with one request. */
|
||||||
|
interface FilterCountersFilters {
|
||||||
|
[FilterCounterEntityType.TASK]: TaskFilterCloudModel[];
|
||||||
|
[FilterCounterEntityType.PROCESS_INSTANCE]: ProcessFilterCloudModel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Payload of the engine event subscription. */
|
||||||
|
type EngineEventsResult = FetchResult<{ engineEvents?: TaskCloudEngineEvent[] }>;
|
||||||
|
|
||||||
const FILTER_COUNTERS_EVENT_SUBSCRIPTION_QUERY = `
|
const FILTER_COUNTERS_EVENT_SUBSCRIPTION_QUERY = `
|
||||||
subscription {
|
subscription {
|
||||||
engineEvents(eventType: [
|
engineEvents(eventType: [
|
||||||
@@ -157,7 +166,7 @@ export class FilterCountersCloudService extends BaseCloudService {
|
|||||||
let events$ = this.eventsPerApp.get(appName);
|
let events$ = this.eventsPerApp.get(appName);
|
||||||
if (!events$) {
|
if (!events$) {
|
||||||
events$ = defer(() => this.notificationCloudService.makeGQLQuery(appName, FILTER_COUNTERS_EVENT_SUBSCRIPTION_QUERY)).pipe(
|
events$ = defer(() => this.notificationCloudService.makeGQLQuery(appName, FILTER_COUNTERS_EVENT_SUBSCRIPTION_QUERY)).pipe(
|
||||||
map((events: any) => (events?.data?.engineEvents ?? []) as TaskCloudEngineEvent[]),
|
map((result: EngineEventsResult) => result.data?.engineEvents ?? []),
|
||||||
debounceTime(this.notificationDebounceTime),
|
debounceTime(this.notificationDebounceTime),
|
||||||
shareReplay({ bufferSize: 1, refCount: true })
|
shareReplay({ bufferSize: 1, refCount: true })
|
||||||
);
|
);
|
||||||
|
|||||||
+2
-1
@@ -37,6 +37,7 @@ import { ActivatedRoute, provideRouter, Router } from '@angular/router';
|
|||||||
import { RouterTestingHarness } from '@angular/router/testing';
|
import { RouterTestingHarness } from '@angular/router/testing';
|
||||||
import { FilterCountersCloudService } from '../../../../services/filter-counters-cloud.service';
|
import { FilterCountersCloudService } from '../../../../services/filter-counters-cloud.service';
|
||||||
import { FilterCounterEntityType } from '../../../../models/filter-counters-cloud.model';
|
import { FilterCounterEntityType } from '../../../../models/filter-counters-cloud.model';
|
||||||
|
import { TaskCloudEngineEvent } from '../../../../models/engine-event-cloud.model';
|
||||||
|
|
||||||
@Component({ selector: 'adf-cloud-dummy', template: '' })
|
@Component({ selector: 'adf-cloud-dummy', template: '' })
|
||||||
class DummyComponent {}
|
class DummyComponent {}
|
||||||
@@ -334,7 +335,7 @@ describe('TaskFiltersCloudComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should emit the events of the debounced batch', fakeAsync(() => {
|
it('should emit the events of the debounced batch', fakeAsync(() => {
|
||||||
const events$ = new Subject<any>();
|
const events$ = new Subject<TaskCloudEngineEvent[]>();
|
||||||
getEngineEventsSpy.and.returnValue(events$.asObservable());
|
getEngineEventsSpy.and.returnValue(events$.asObservable());
|
||||||
const filterCounterUpdatedSpy = spyOn(component.filterCounterUpdated, 'emit');
|
const filterCounterUpdatedSpy = spyOn(component.filterCounterUpdated, 'emit');
|
||||||
component.appName = 'my-app-1';
|
component.appName = 'my-app-1';
|
||||||
|
|||||||
Reference in New Issue
Block a user