1 import metrics from '@proton/metrics';
2 import { EVENT_TYPES } from '@proton/shared/lib/drive/constants';
3 import type { DriveEventsResult } from '@proton/shared/lib/interfaces/drive/events';
5 import type { DriveEvent } from '.';
6 import type { EncryptedLink } from '../_links';
7 import { VolumeType } from '../_volumes';
8 import { EventsMetrics, countEventsPerType } from './driveEventsMetrics';
10 jest.mock('@proton/metrics', () => ({
11 drive_sync_event_total: {
14 drive_sync_event_unecessary_total: {
19 describe('EventsMetrics', () => {
20 let eventsMetrics: EventsMetrics;
23 eventsMetrics = new EventsMetrics();
27 test('processed method adds events correctly', () => {
28 const event: DriveEvent = {
29 eventType: EVENT_TYPES.CREATE,
30 encryptedLink: { volumeId: 'vol1', linkId: 'link1' } as EncryptedLink,
32 eventsMetrics.processed('event1', event);
34 const state = (eventsMetrics as any).state;
35 expect(state.get('vol1-event1')).toEqual({
36 create: new Set(['link1']),
40 test('batchStart method initializes events correctly', () => {
41 const driveEvents: DriveEventsResult = {
44 { EventType: EVENT_TYPES.CREATE, Link: { LinkID: 'link1' } },
45 { EventType: EVENT_TYPES.DELETE, Link: { LinkID: 'link2' } },
47 } as DriveEventsResult;
48 eventsMetrics.batchStart('vol1', driveEvents);
50 const events = (eventsMetrics as any).events;
51 expect(events.get('vol1-event1')).toEqual({
52 create: new Set(['link1']),
53 delete: new Set(['link2']),
55 update_metadata: new Set(),
59 test('batchCompleted method processes batch correctly', () => {
60 const driveEvents: DriveEventsResult = {
63 { EventType: EVENT_TYPES.CREATE, Link: { LinkID: 'link1' } },
64 { EventType: EVENT_TYPES.DELETE, Link: { LinkID: 'link2' } },
66 } as DriveEventsResult;
67 eventsMetrics.batchStart('vol1', driveEvents);
68 eventsMetrics.processed('event1', {
69 eventType: EVENT_TYPES.CREATE,
70 encryptedLink: { volumeId: 'vol1', linkId: 'link1' } as EncryptedLink,
72 eventsMetrics.batchCompleted('vol1', 'event1', VolumeType.main);
74 expect(metrics.drive_sync_event_unecessary_total.increment).toHaveBeenCalledWith(
75 { volumeType: VolumeType.main, eventType: 'delete' },
81 describe('countEventsPerType', () => {
86 test('counts events correctly', () => {
87 const driveEvents: DriveEventsResult = {
89 { EventType: EVENT_TYPES.CREATE },
90 { EventType: EVENT_TYPES.UPDATE },
91 { EventType: EVENT_TYPES.UPDATE },
92 { EventType: EVENT_TYPES.DELETE },
93 { EventType: EVENT_TYPES.UPDATE_METADATA },
95 } as DriveEventsResult;
97 countEventsPerType(VolumeType.main, driveEvents);
99 expect(metrics.drive_sync_event_total.increment).toHaveBeenCalledTimes(4);
100 expect(metrics.drive_sync_event_total.increment).toHaveBeenCalledWith(
101 { volumeType: VolumeType.main, eventType: 'create' },
104 expect(metrics.drive_sync_event_total.increment).toHaveBeenCalledWith(
105 { volumeType: VolumeType.main, eventType: 'update' },
108 expect(metrics.drive_sync_event_total.increment).toHaveBeenCalledWith(
109 { volumeType: VolumeType.main, eventType: 'delete' },
112 expect(metrics.drive_sync_event_total.increment).toHaveBeenCalledWith(
113 { volumeType: VolumeType.main, eventType: 'update_metadata' },
118 test('handles undefined events', () => {
119 const driveEvents: DriveEventsResult = {} as DriveEventsResult;
120 countEventsPerType(VolumeType.main, driveEvents);
121 expect(metrics.drive_sync_event_total.increment).not.toHaveBeenCalled();