-
Notifications
You must be signed in to change notification settings - Fork 1
🎨 Palette: Add progress bar for fetching existing rules #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| ## PALETTE'S JOURNAL - CRITICAL LEARNINGS ONLY | ||
|
|
||
| This journal is for recording critical UX/accessibility learnings. | ||
|
|
||
| --- | ||
|
|
||
| ## 2024-05-23 - CLI Progress Bars in Parallel Operations | ||
| **Learning:** Adding visual feedback (progress bars) to parallel operations (like `ThreadPoolExecutor`) requires careful management of `stderr`. Standard logging (`logging.warning`) can interfere with `\r` carriage returns used for progress bars. | ||
| **Action:** Always clear the line (`\r\033[K`) before logging warnings inside a progress-tracked loop, and redraw the progress bar afterwards if necessary. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,7 +51,7 @@ | |
| monkeypatch.setattr(m, "list_existing_folders", mock_list_folders) | ||
|
|
||
| # Mock _api_get to return different rules for root vs folders | ||
| def side_effect(client, url): | ||
Check warningCode scanning / Pylint (reported by Codacy) Missing function docstring Warning test
Missing function docstring
Check noticeCode scanning / Pylint (reported by Codacy) Unused argument 'client' Note test
Unused argument 'client'
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Unused argument 'client' Note test
Unused argument 'client'
|
||
| mock_resp = MagicMock() | ||
| if url.endswith("/rules"): # Root rules | ||
| mock_resp.json.return_value = {"body": {"rules": [{"PK": "rule_root"}]}} | ||
|
|
@@ -174,7 +174,7 @@ | |
|
|
||
| # Case 5: push_rules writes colored progress and completion messages to stderr when USE_COLORS is True | ||
| def test_push_rules_writes_colored_stderr(monkeypatch): | ||
| m = reload_main_with_env(monkeypatch, no_color=None, isatty=True) | ||
Check warningCode scanning / Pylint (reported by Codacy) Variable name "m" doesn't conform to snake_case naming style Warning test
Variable name "m" doesn't conform to snake_case naming style
Check warningCode scanning / Pylintpython3 (reported by Codacy) Variable name "m" doesn't conform to snake_case naming style Warning test
Variable name "m" doesn't conform to snake_case naming style
|
||
| monkeypatch.setattr(m, "_api_post_form", MagicMock()) | ||
|
|
||
| mock_stderr = MagicMock() | ||
|
|
@@ -510,3 +510,37 @@ | |
| # Color codes (accessing instance Colors or m.Colors) | ||
| assert m.Colors.CYAN in combined | ||
| assert m.Colors.ENDC in combined | ||
|
|
||
| # Case 14: get_all_existing_rules shows progress bar | ||
| def test_get_all_existing_rules_shows_progress(monkeypatch): | ||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Missing function or method docstring Warning test
Missing function or method docstring
Check warningCode scanning / Pylint (reported by Codacy) Missing function docstring Warning test
Missing function docstring
|
||
| m = reload_main_with_env(monkeypatch, no_color=None, isatty=True) | ||
| mock_client = MagicMock() | ||
| profile_id = "test_profile" | ||
|
|
||
| mock_stderr = MagicMock() | ||
| monkeypatch.setattr(sys, "stderr", mock_stderr) | ||
|
|
||
| # Mock list_existing_folders to return multiple folders | ||
| folders = {f"Folder{i}": f"id_{i}" for i in range(5)} | ||
| monkeypatch.setattr(m, "list_existing_folders", MagicMock(return_value=folders)) | ||
|
|
||
| # Mock _api_get | ||
| def side_effect(client, url): | ||
Check warningCode scanning / Prospector (reported by Codacy) Unused argument 'client' (unused-argument) Warning test
Unused argument 'client' (unused-argument)
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Unused argument 'url' Note test
Unused argument 'url'
Check warningCode scanning / Prospector (reported by Codacy) Unused argument 'url' (unused-argument) Warning test
Unused argument 'url' (unused-argument)
Check noticeCode scanning / Pylint (reported by Codacy) Unused argument 'client' Note test
Unused argument 'client'
|
||
| mock_resp = MagicMock() | ||
| mock_resp.json.return_value = {"body": {"rules": []}} | ||
| return mock_resp | ||
| monkeypatch.setattr(m, "_api_get", side_effect) | ||
|
|
||
| # Run | ||
| m.get_all_existing_rules(mock_client, profile_id) | ||
|
|
||
| # Check that progress bar logic was invoked | ||
| # render_progress_bar writes to stderr with \r... | ||
| # We check if there were writes containing "Fetching existing rules" | ||
| writes = [str(args[0]) for args, _ in mock_stderr.write.call_args_list] | ||
| progress_writes = [w for w in writes if "Fetching existing rules" in w] | ||
|
|
||
| assert len(progress_writes) > 0 | ||
Check noticeCode scanning / Bandit Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
|
||
| # Should be called initially (0/5) + for each folder (1/5 ... 5/5) | ||
| # Total calls >= 6 | ||
| assert len(progress_writes) >= 6 | ||
Check noticeCode scanning / Bandit Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A security vulnerability exists here: the
folder_idand exceptioneare interpolated directly into the log message without sanitization. Sincefolder_idcomes from an external API andecan contain untrusted data, this could allow an attacker to inject ANSI escape sequences into the terminal, leading to terminal hijacking or log injection. Please use the existingsanitize_for_logfunction to prevent this. Additionally, ensure that exceptions from the_fetch_folder_rulesfunction are properly re-raised and propagate to thisexceptblock, as logging directly from worker threads can interfere with the progress bar rendering and this handler might not be triggered as expected.