1
1
import { IpcMainEvent , ipcMain } from 'electron' ;
2
2
import fs from 'node:fs' ;
3
3
import path from 'node:path' ;
4
- import { beforeEach , describe , expect , it , vi } from 'vitest' ;
4
+ import { Mock , beforeEach , describe , expect , it , vi } from 'vitest' ;
5
5
6
- import { MixpanelTelemetry } from '../../src/services/telemetry' ;
6
+ import { MixpanelTelemetry , promptMetricsConsent } from '../../src/services/telemetry' ;
7
7
import { IPC_CHANNELS } from '/src/constants' ;
8
8
9
9
vi . mock ( 'electron' , ( ) => ( {
@@ -14,6 +14,8 @@ vi.mock('electron', () => ({
14
14
ipcMain : {
15
15
on : vi . fn ( ) ,
16
16
once : vi . fn ( ) ,
17
+ handle : vi . fn ( ) ,
18
+ removeHandler : vi . fn ( ) ,
17
19
} ,
18
20
} ) ) ;
19
21
@@ -185,3 +187,166 @@ describe('MixpanelTelemetry', () => {
185
187
expect ( telemetry [ 'mixpanelClient' ] ) . toBe ( mockInitializedClient ) ;
186
188
} ) ;
187
189
} ) ;
190
+
191
+ describe ( 'promptMetricsConsent' , ( ) => {
192
+ let store : { get : Mock ; set : Mock } ;
193
+ let appWindow : { loadRenderer : Mock } ;
194
+ let comfyDesktopApp : { comfySettings : { get : Mock } } ;
195
+
196
+ const versionBeforeUpdate = '0.4.1' ;
197
+ const versionAfterUpdate = '1.0.1' ;
198
+
199
+ beforeEach ( ( ) => {
200
+ vi . clearAllMocks ( ) ;
201
+ store = { get : vi . fn ( ) , set : vi . fn ( ) } ;
202
+ appWindow = { loadRenderer : vi . fn ( ) } ;
203
+ comfyDesktopApp = { comfySettings : { get : vi . fn ( ) } } ;
204
+ } ) ;
205
+
206
+ const runTest = async ( {
207
+ storeValue,
208
+ settingsValue,
209
+ expectedResult,
210
+ mockConsent,
211
+ promptUser,
212
+ } : {
213
+ storeValue : string | null | undefined ;
214
+ settingsValue : boolean | null | undefined ;
215
+ expectedResult : boolean ;
216
+ mockConsent ?: boolean ;
217
+ promptUser ?: boolean ;
218
+ } ) => {
219
+ store . get . mockReturnValue ( storeValue ) ;
220
+ comfyDesktopApp . comfySettings . get . mockReturnValue ( settingsValue ) ;
221
+
222
+ if ( promptUser ) {
223
+ vi . mocked ( ipcMain . handle ) . mockImplementationOnce ( ( channel , handler ) => {
224
+ if ( channel === IPC_CHANNELS . SET_METRICS_CONSENT ) {
225
+ // @ts -expect-error - handler is a mock and doesn't implement the correct signature
226
+ handler ( null , mockConsent ) ;
227
+ }
228
+ } ) ;
229
+ }
230
+
231
+ // @ts -expect-error - store is a mock and doesn't implement all of DesktopConfig
232
+ const result = await promptMetricsConsent ( store , appWindow , comfyDesktopApp ) ;
233
+ expect ( result ) . toBe ( expectedResult ) ;
234
+
235
+ if ( promptUser ) ipcMain . removeHandler ( IPC_CHANNELS . SET_METRICS_CONSENT ) ;
236
+ } ;
237
+
238
+ it ( 'should prompt for update if metrics were previously enabled' , async ( ) => {
239
+ await runTest ( {
240
+ storeValue : versionBeforeUpdate ,
241
+ settingsValue : true ,
242
+ expectedResult : true ,
243
+ mockConsent : true ,
244
+ promptUser : true ,
245
+ } ) ;
246
+ expect ( store . set ) . toHaveBeenCalled ( ) ;
247
+ expect ( appWindow . loadRenderer ) . toHaveBeenCalledWith ( 'metrics-consent' ) ;
248
+ expect ( ipcMain . handle ) . toHaveBeenCalledWith ( IPC_CHANNELS . SET_METRICS_CONSENT , expect . any ( Function ) ) ;
249
+ } ) ;
250
+
251
+ it ( 'should not show prompt if consent is up-to-date' , async ( ) => {
252
+ await runTest ( {
253
+ storeValue : versionAfterUpdate ,
254
+ settingsValue : true ,
255
+ expectedResult : true ,
256
+ } ) ;
257
+ expect ( store . get ) . toHaveBeenCalledWith ( 'versionConsentedMetrics' ) ;
258
+ expect ( store . set ) . not . toHaveBeenCalled ( ) ;
259
+ expect ( appWindow . loadRenderer ) . not . toHaveBeenCalled ( ) ;
260
+ expect ( ipcMain . handle ) . not . toHaveBeenCalled ( ) ;
261
+ } ) ;
262
+
263
+ it ( 'should return true if consent is up-to-date and metrics enabled' , async ( ) => {
264
+ await runTest ( {
265
+ storeValue : versionAfterUpdate ,
266
+ settingsValue : true ,
267
+ expectedResult : true ,
268
+ } ) ;
269
+ expect ( store . set ) . not . toHaveBeenCalled ( ) ;
270
+ } ) ;
271
+
272
+ it ( 'should return false if consent is up-to-date and metrics are disabled' , async ( ) => {
273
+ await runTest ( {
274
+ storeValue : versionAfterUpdate ,
275
+ settingsValue : false ,
276
+ expectedResult : false ,
277
+ } ) ;
278
+ expect ( store . set ) . not . toHaveBeenCalled ( ) ;
279
+ expect ( appWindow . loadRenderer ) . not . toHaveBeenCalled ( ) ;
280
+ expect ( ipcMain . handle ) . not . toHaveBeenCalled ( ) ;
281
+ } ) ;
282
+
283
+ it ( 'should return false if consent is out-of-date and metrics are disabled' , async ( ) => {
284
+ await runTest ( {
285
+ storeValue : versionBeforeUpdate ,
286
+ settingsValue : false ,
287
+ expectedResult : false ,
288
+ } ) ;
289
+ expect ( store . set ) . toHaveBeenCalled ( ) ;
290
+ expect ( appWindow . loadRenderer ) . not . toHaveBeenCalled ( ) ;
291
+ expect ( ipcMain . handle ) . not . toHaveBeenCalled ( ) ;
292
+ } ) ;
293
+
294
+ it ( 'should update consent to false if the user denies' , async ( ) => {
295
+ await runTest ( {
296
+ storeValue : versionBeforeUpdate ,
297
+ settingsValue : true ,
298
+ expectedResult : false ,
299
+ mockConsent : false ,
300
+ promptUser : true ,
301
+ } ) ;
302
+ expect ( store . set ) . toHaveBeenCalled ( ) ;
303
+ expect ( appWindow . loadRenderer ) . toHaveBeenCalledWith ( 'metrics-consent' ) ;
304
+ expect ( ipcMain . handle ) . toHaveBeenCalledWith ( IPC_CHANNELS . SET_METRICS_CONSENT , expect . any ( Function ) ) ;
305
+ } ) ;
306
+
307
+ it ( 'should return false if previous metrics setting is null' , async ( ) => {
308
+ await runTest ( {
309
+ storeValue : versionBeforeUpdate ,
310
+ settingsValue : null ,
311
+ expectedResult : false ,
312
+ } ) ;
313
+ expect ( store . set ) . toHaveBeenCalled ( ) ;
314
+ expect ( appWindow . loadRenderer ) . not . toHaveBeenCalled ( ) ;
315
+ expect ( ipcMain . handle ) . not . toHaveBeenCalled ( ) ;
316
+ } ) ;
317
+
318
+ it ( 'should prompt for update if versionConsentedMetrics is undefined' , async ( ) => {
319
+ await runTest ( {
320
+ storeValue : undefined ,
321
+ settingsValue : true ,
322
+ expectedResult : true ,
323
+ mockConsent : true ,
324
+ promptUser : true ,
325
+ } ) ;
326
+ expect ( store . set ) . toHaveBeenCalled ( ) ;
327
+ expect ( appWindow . loadRenderer ) . toHaveBeenCalledWith ( 'metrics-consent' ) ;
328
+ expect ( ipcMain . handle ) . toHaveBeenCalledWith ( IPC_CHANNELS . SET_METRICS_CONSENT , expect . any ( Function ) ) ;
329
+ } ) ;
330
+
331
+ it ( 'should return false if both settings are null or undefined' , async ( ) => {
332
+ await runTest ( {
333
+ storeValue : null ,
334
+ settingsValue : null ,
335
+ expectedResult : false ,
336
+ } ) ;
337
+ expect ( store . set ) . toHaveBeenCalled ( ) ;
338
+ expect ( appWindow . loadRenderer ) . not . toHaveBeenCalled ( ) ;
339
+ expect ( ipcMain . handle ) . not . toHaveBeenCalled ( ) ;
340
+ } ) ;
341
+
342
+ it ( 'should return false if metrics are disabled and consent is null' , async ( ) => {
343
+ await runTest ( {
344
+ storeValue : versionBeforeUpdate ,
345
+ settingsValue : null ,
346
+ expectedResult : false ,
347
+ } ) ;
348
+ expect ( store . set ) . toHaveBeenCalled ( ) ;
349
+ expect ( appWindow . loadRenderer ) . not . toHaveBeenCalled ( ) ;
350
+ expect ( ipcMain . handle ) . not . toHaveBeenCalled ( ) ;
351
+ } ) ;
352
+ } ) ;
0 commit comments