@@ -280,3 +280,101 @@ def test_session_only_is_idempotent(self, tracking_module):
280280 first_user_id = tracking_module .user_id
281281 tracking_module .prompt_tracking_consent ()
282282 assert tracking_module .user_id == first_user_id
283+
284+
285+ class TestEnvVarOptOut :
286+ @pytest .mark .parametrize ("env_var" , ["DO_NOT_TRACK" , "COMFY_NO_TELEMETRY" ])
287+ def test_env_var_blocks_track_event_even_when_config_enabled (self , tracking_module , monkeypatch , env_var ):
288+ tracking_module .config_manager .set (constants .CONFIG_KEY_ENABLE_TRACKING , "True" )
289+ monkeypatch .setenv (env_var , "1" )
290+ tracking_module .track_event ("some_event" , {"k" : "v" })
291+ tracking_module .provider .track .assert_not_called ()
292+
293+ @pytest .mark .parametrize ("env_var" , ["DO_NOT_TRACK" , "COMFY_NO_TELEMETRY" ])
294+ def test_env_var_blocks_track_event_under_session_only (self , tracking_module , monkeypatch , env_var ):
295+ monkeypatch .setenv (env_var , "1" )
296+ with patch .object (tracking_module , "_session_only_tracking" , True ):
297+ tracking_module .track_event ("some_event" )
298+ tracking_module .provider .track .assert_not_called ()
299+
300+ @pytest .mark .parametrize ("falsy" , ["" , "0" ])
301+ def test_falsy_values_do_not_block (self , tracking_module , monkeypatch , falsy ):
302+ tracking_module .config_manager .set (constants .CONFIG_KEY_ENABLE_TRACKING , "True" )
303+ monkeypatch .setenv ("DO_NOT_TRACK" , falsy )
304+ monkeypatch .setenv ("COMFY_NO_TELEMETRY" , falsy )
305+ tracking_module .track_event ("some_event" )
306+ tracking_module .provider .track .assert_called_once ()
307+
308+ @pytest .mark .parametrize ("env_var" , ["DO_NOT_TRACK" , "COMFY_NO_TELEMETRY" ])
309+ def test_env_var_short_circuits_consent_prompt (self , tracking_module , monkeypatch , env_var ):
310+ monkeypatch .setenv (env_var , "1" )
311+ with (
312+ patch .object (tracking_module .sys .stdin , "isatty" , return_value = True ),
313+ patch .object (tracking_module .sys .stdout , "isatty" , return_value = True ),
314+ patch .object (tracking_module .ui , "prompt_confirm_action" ) as mock_prompt ,
315+ ):
316+ tracking_module .prompt_tracking_consent ()
317+ mock_prompt .assert_not_called ()
318+ assert tracking_module .config_manager .get_bool (constants .CONFIG_KEY_ENABLE_TRACKING ) is None
319+
320+ @pytest .mark .parametrize ("env_var" , ["DO_NOT_TRACK" , "COMFY_NO_TELEMETRY" ])
321+ def test_env_var_blocks_non_tty_auto_enable_and_user_id_persist (self , tracking_module , monkeypatch , env_var ):
322+ # Reporter's core concern (issue #462): in CI/Docker the non-TTY
323+ # branch silently persisted a UUID. Env var must skip that path.
324+ monkeypatch .setenv (env_var , "1" )
325+ with (
326+ patch .object (tracking_module .sys .stdin , "isatty" , return_value = False ),
327+ patch .object (tracking_module .sys .stdout , "isatty" , return_value = False ),
328+ ):
329+ tracking_module .prompt_tracking_consent ()
330+ assert tracking_module ._session_only_tracking is False
331+ assert tracking_module .config_manager .get (constants .CONFIG_KEY_USER_ID ) is None
332+
333+ def test_env_var_does_not_overwrite_existing_consent (self , tracking_module , monkeypatch ):
334+ # On-disk consent flag must survive an env-var-suppressed run so a
335+ # subsequent invocation without the env var keeps the user's choice.
336+ tracking_module .config_manager .set (constants .CONFIG_KEY_ENABLE_TRACKING , "True" )
337+ monkeypatch .setenv ("DO_NOT_TRACK" , "1" )
338+ tracking_module .prompt_tracking_consent ()
339+ assert tracking_module .config_manager .get_bool (constants .CONFIG_KEY_ENABLE_TRACKING ) is True
340+
341+
342+ class TestTelemetryDisabledByEnvHelper :
343+ @pytest .fixture (autouse = True )
344+ def _clear_both (self , monkeypatch ):
345+ monkeypatch .delenv ("DO_NOT_TRACK" , raising = False )
346+ monkeypatch .delenv ("COMFY_NO_TELEMETRY" , raising = False )
347+
348+ def test_unset_returns_false (self , tracking_module ):
349+ import comfy_cli .tracking as tm
350+
351+ assert tm ._telemetry_disabled_by_env () is False
352+
353+ @pytest .mark .parametrize ("env_var" , ["DO_NOT_TRACK" , "COMFY_NO_TELEMETRY" ])
354+ @pytest .mark .parametrize (
355+ "value,expected" ,
356+ [
357+ # consoledonottrack.com spec: empty or "0" allows tracking; anything else opts out.
358+ ("" , False ),
359+ ("0" , False ),
360+ ("1" , True ),
361+ ("true" , True ),
362+ ("yes" , True ),
363+ ("00" , True ),
364+ ("false" , True ),
365+ ],
366+ )
367+ def test_value_semantics (self , tracking_module , monkeypatch , env_var , value , expected ):
368+ import comfy_cli .tracking as tm
369+
370+ monkeypatch .setenv (env_var , value )
371+ assert tm ._telemetry_disabled_by_env () is expected
372+
373+ def test_either_var_alone_is_sufficient (self , tracking_module , monkeypatch ):
374+ import comfy_cli .tracking as tm
375+
376+ monkeypatch .setenv ("COMFY_NO_TELEMETRY" , "1" )
377+ assert tm ._telemetry_disabled_by_env () is True
378+ monkeypatch .delenv ("COMFY_NO_TELEMETRY" )
379+ monkeypatch .setenv ("DO_NOT_TRACK" , "1" )
380+ assert tm ._telemetry_disabled_by_env () is True
0 commit comments