source_monitor 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/commands/release.md +45 -22
- data/.claude/skills/sm-configure/SKILL.md +10 -1
- data/.claude/skills/sm-configure/reference/configuration-reference.md +44 -0
- data/.claude/skills/sm-host-setup/reference/initializer-template.md +17 -0
- data/.claude/skills/sm-host-setup/reference/setup-checklist.md +2 -0
- data/.claude/skills/sm-job/reference/job-conventions.md +26 -0
- data/.claude/skills/sm-upgrade/reference/version-history.md +22 -0
- data/.gitignore +10 -0
- data/AGENTS.md +1 -1
- data/CHANGELOG.md +56 -0
- data/CLAUDE.md +11 -5
- data/Gemfile.lock +1 -1
- data/README.md +6 -4
- data/VERSION +1 -1
- data/app/assets/builds/source_monitor/application.css +43 -0
- data/app/assets/builds/source_monitor/application.js +127 -0
- data/app/assets/builds/source_monitor/application.js.map +3 -3
- data/app/assets/javascripts/source_monitor/application.js +2 -0
- data/app/assets/javascripts/source_monitor/controllers/notification_container_controller.js +138 -0
- data/app/assets/javascripts/source_monitor/controllers/notification_controller.js +11 -0
- data/app/controllers/source_monitor/source_favicon_fetches_controller.rb +38 -0
- data/app/controllers/source_monitor/sources_controller.rb +11 -0
- data/app/helpers/source_monitor/application_helper.rb +51 -0
- data/app/jobs/source_monitor/favicon_fetch_job.rb +71 -0
- data/app/jobs/source_monitor/import_opml_job.rb +9 -0
- data/app/jobs/source_monitor/source_health_check_job.rb +10 -0
- data/app/models/source_monitor/source.rb +2 -0
- data/app/views/layouts/source_monitor/application.html.erb +23 -2
- data/app/views/source_monitor/shared/_toast.html.erb +1 -0
- data/app/views/source_monitor/sources/_details.html.erb +34 -5
- data/app/views/source_monitor/sources/_row.html.erb +11 -6
- data/config/routes.rb +1 -0
- data/docs/configuration.md +1 -1
- data/docs/upgrade.md +22 -0
- data/lib/generators/source_monitor/install/templates/source_monitor.rb.tt +15 -1
- data/lib/source_monitor/configuration/favicons_settings.rb +42 -0
- data/lib/source_monitor/configuration/http_settings.rb +1 -1
- data/lib/source_monitor/configuration/scraping_settings.rb +1 -1
- data/lib/source_monitor/configuration.rb +3 -1
- data/lib/source_monitor/favicons/discoverer.rb +196 -0
- data/lib/source_monitor/fetching/feed_fetcher/source_updater.rb +21 -0
- data/lib/source_monitor/fetching/feed_fetcher.rb +1 -0
- data/lib/source_monitor/http.rb +5 -3
- data/lib/source_monitor/version.rb +1 -1
- data/lib/source_monitor.rb +4 -0
- data/lib/tasks/test_fast.rake +11 -0
- data/source_monitor.gemspec +1 -1
- metadata +7 -93
- data/.vbw-planning/PROJECT.md +0 -51
- data/.vbw-planning/ROADMAP.md +0 -32
- data/.vbw-planning/SHIPPED.md +0 -63
- data/.vbw-planning/STATE.md +0 -27
- data/.vbw-planning/codebase/ARCHITECTURE.md +0 -147
- data/.vbw-planning/codebase/CONCERNS.md +0 -99
- data/.vbw-planning/codebase/CONVENTIONS.md +0 -97
- data/.vbw-planning/codebase/DEPENDENCIES.md +0 -100
- data/.vbw-planning/codebase/INDEX.md +0 -86
- data/.vbw-planning/codebase/META.md +0 -42
- data/.vbw-planning/codebase/PATTERNS.md +0 -262
- data/.vbw-planning/codebase/STACK.md +0 -101
- data/.vbw-planning/codebase/STRUCTURE.md +0 -324
- data/.vbw-planning/codebase/TESTING.md +0 -154
- data/.vbw-planning/config.json +0 -53
- data/.vbw-planning/discovery.json +0 -26
- data/.vbw-planning/milestones/default/ROADMAP.md +0 -115
- data/.vbw-planning/milestones/default/STATE.md +0 -82
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01-SUMMARY.md +0 -56
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01.md +0 -187
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02-SUMMARY.md +0 -64
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02.md +0 -137
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01-SUMMARY.md +0 -67
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01.md +0 -142
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02-SUMMARY.md +0 -64
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02.md +0 -138
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03-SUMMARY.md +0 -85
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03.md +0 -147
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04-SUMMARY.md +0 -63
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04.md +0 -129
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05-SUMMARY.md +0 -74
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05.md +0 -154
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION-wave1.md +0 -303
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION.md +0 -510
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01-SUMMARY.md +0 -61
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01.md +0 -161
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02-SUMMARY.md +0 -66
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02.md +0 -132
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03-SUMMARY.md +0 -59
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03.md +0 -171
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04-SUMMARY.md +0 -56
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04.md +0 -152
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/04-CONTEXT.md +0 -33
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01-SUMMARY.md +0 -42
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01.md +0 -119
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02-SUMMARY.md +0 -52
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02.md +0 -195
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03-SUMMARY.md +0 -79
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03.md +0 -130
- data/.vbw-planning/milestones/generator-enhancements/REQUIREMENTS.md +0 -72
- data/.vbw-planning/milestones/generator-enhancements/ROADMAP.md +0 -125
- data/.vbw-planning/milestones/generator-enhancements/SHIPPED.md +0 -40
- data/.vbw-planning/milestones/generator-enhancements/STATE.md +0 -43
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/01-CONTEXT.md +0 -33
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/01-VERIFICATION.md +0 -86
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/PLAN-01-SUMMARY.md +0 -61
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/PLAN-01.md +0 -380
- data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/02-VERIFICATION.md +0 -78
- data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/PLAN-01-SUMMARY.md +0 -46
- data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/PLAN-01.md +0 -500
- data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/03-VERIFICATION.md +0 -89
- data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/PLAN-01-SUMMARY.md +0 -48
- data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/PLAN-01.md +0 -456
- data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/04-VERIFICATION.md +0 -129
- data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/PLAN-01-SUMMARY.md +0 -70
- data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/PLAN-01.md +0 -747
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/05-VERIFICATION.md +0 -156
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-01-SUMMARY.md +0 -69
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-01.md +0 -455
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-02-SUMMARY.md +0 -39
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-02.md +0 -488
- data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/06-VERIFICATION.md +0 -100
- data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/PLAN-01-SUMMARY.md +0 -37
- data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/PLAN-01.md +0 -345
- data/.vbw-planning/milestones/upgrade-assurance/REQUIREMENTS.md +0 -80
- data/.vbw-planning/milestones/upgrade-assurance/ROADMAP.md +0 -75
- data/.vbw-planning/milestones/upgrade-assurance/STATE.md +0 -29
- data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/01-VERIFICATION.md +0 -144
- data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/PLAN-01-SUMMARY.md +0 -43
- data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/PLAN-01.md +0 -405
- data/.vbw-planning/milestones/upgrade-assurance/phases/02-config-deprecation/PLAN-01-SUMMARY.md +0 -27
- data/.vbw-planning/milestones/upgrade-assurance/phases/02-config-deprecation/PLAN-01.md +0 -303
- data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/03-VERIFICATION.md +0 -380
- data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/PLAN-01-SUMMARY.md +0 -36
- data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/PLAN-01.md +0 -652
- data/.vbw-planning/phases/01-aia-certificate-resolution/.context-dev.md +0 -17
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-01-SUMMARY.md +0 -26
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-01.md +0 -71
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-02-SUMMARY.md +0 -16
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-02.md +0 -56
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-03-SUMMARY.md +0 -17
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-03.md +0 -98
data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03-SUMMARY.md
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# PLAN-03 Summary: configuration-tests
|
|
2
|
-
|
|
3
|
-
## Status: COMPLETE
|
|
4
|
-
|
|
5
|
-
## Commit
|
|
6
|
-
|
|
7
|
-
- **Hash:** `66b8df2`
|
|
8
|
-
- **Message:** `test(dev-plan05): close coverage gaps for bulk scraper and broadcaster`
|
|
9
|
-
- **Files changed:** 1 file (configuration_test.rb), 771 insertions
|
|
10
|
-
- **Note:** Commit was mislabeled as "dev-plan05" but the code changes are configuration tests matching Plan 03 tasks exactly.
|
|
11
|
-
|
|
12
|
-
## Tasks Completed
|
|
13
|
-
|
|
14
|
-
### Task 1: Test AuthenticationSettings handlers (lines 75-130)
|
|
15
|
-
- Tested authenticate_with :symbol handler dispatches via public_send
|
|
16
|
-
- Tested authenticate_with string handler converts to symbol
|
|
17
|
-
- Tested authenticate_with callable with zero arity uses instance_exec
|
|
18
|
-
- Tested authenticate_with callable with arity passes controller
|
|
19
|
-
- Tested authenticate_with block handler
|
|
20
|
-
- Tested authorize_with symbol and callable handlers
|
|
21
|
-
- Tested Handler.call returns nil when callable is nil
|
|
22
|
-
- Tested invalid handler raises ArgumentError
|
|
23
|
-
- Tested reset! clears all handlers and methods
|
|
24
|
-
- Tested authenticate_with nil returns nil handler
|
|
25
|
-
|
|
26
|
-
### Task 2: Test ScrapingSettings and RetentionSettings edge cases (lines 132-164, 398-436)
|
|
27
|
-
- Tested ScrapingSettings defaults (max_in_flight_per_source=25, max_bulk_batch_size=100)
|
|
28
|
-
- Tested normalize_numeric: string, nil, empty string, zero, negative all handled correctly
|
|
29
|
-
- Tested ScrapingSettings reset restores defaults
|
|
30
|
-
- Tested RetentionSettings defaults (nil for days/max_items, :destroy strategy)
|
|
31
|
-
- Tested strategy accepts :soft_delete, string "destroy", rejects :archive and non-symbolizable
|
|
32
|
-
- Tested strategy normalizes nil to :destroy
|
|
33
|
-
|
|
34
|
-
### Task 3: Test RealtimeSettings adapter validation and action_cable_config (lines 166-253)
|
|
35
|
-
- Tested adapter= accepts :solid_cable, :redis, :async; rejects :websocket and nil
|
|
36
|
-
- Tested action_cable_config for solid_cable returns merged SolidCableOptions
|
|
37
|
-
- Tested action_cable_config for redis with/without url
|
|
38
|
-
- Tested action_cable_config for async returns { adapter: "async" }
|
|
39
|
-
- Tested SolidCableOptions.assign with hash, unknown keys, non-enumerable input
|
|
40
|
-
- Tested SolidCableOptions.to_h compacts nil values
|
|
41
|
-
- Tested realtime reset restores defaults
|
|
42
|
-
|
|
43
|
-
### Task 4: Test Events callbacks and item_processors (lines 438-491)
|
|
44
|
-
- Tested after_item_created with lambda and block registration
|
|
45
|
-
- Tested after_item_scraped and after_fetch_completed registration
|
|
46
|
-
- Tested multiple callbacks per event, callbacks_for unknown key returns []
|
|
47
|
-
- Tested callbacks_for returns dup preventing mutation
|
|
48
|
-
- Tested non-callable handler rejection (ArgumentError)
|
|
49
|
-
- Tested register_item_processor with lambda, block, multiple, dup protection
|
|
50
|
-
- Tested events reset! clears callbacks and item_processors
|
|
51
|
-
|
|
52
|
-
### Task 5: Test Models, ModelDefinition, ConcernDefinition, ValidationDefinition (lines 493-652)
|
|
53
|
-
- Tested Models.table_name_prefix default "sourcemon_"
|
|
54
|
-
- Tested Models exposes all model keys, for(:source) returns definition
|
|
55
|
-
- Tested Models.for(:unknown) raises ArgumentError
|
|
56
|
-
- Tested include_concern with Module, block (anonymous module), string constant
|
|
57
|
-
- Tested include_concern deduplication by signature (module, string, blocks differ)
|
|
58
|
-
- Tested include_concern with invalid string raises on resolve
|
|
59
|
-
- Tested validate with symbol, string, lambda, block; raises on invalid handler
|
|
60
|
-
- Tested ValidationDefinition.signature for symbol, string, callable handlers
|
|
61
|
-
- Tested each_concern returns Enumerator without block
|
|
62
|
-
|
|
63
|
-
## Deviations
|
|
64
|
-
|
|
65
|
-
| ID | Description | Impact |
|
|
66
|
-
|----|-------------|--------|
|
|
67
|
-
| DEVN-01 | Commit mislabeled as "dev-plan05" | None -- code changes are correct Plan 03 configuration tests |
|
|
68
|
-
| DEVN-02 | Parallel test runner segfaults on PG fork when running single file | Tests pass with PARALLEL_WORKERS=1 and in full suite; environment issue, not code defect |
|
|
69
|
-
|
|
70
|
-
## Verification Results
|
|
71
|
-
|
|
72
|
-
| Check | Result |
|
|
73
|
-
|-------|--------|
|
|
74
|
-
| `PARALLEL_WORKERS=1 bin/rails test test/lib/source_monitor/configuration_test.rb` | 81 runs, 178 assertions, 0 failures, 0 errors, 0 skips |
|
|
75
|
-
| `bin/rails test` (full suite) | 760 runs, 2626 assertions, 0 failures, 0 errors, 0 skips |
|
|
76
|
-
|
|
77
|
-
## Success Criteria
|
|
78
|
-
|
|
79
|
-
- [x] 81 tests total (76 new, 5 existing), 771 lines added
|
|
80
|
-
- [x] AuthenticationSettings handlers fully tested
|
|
81
|
-
- [x] ScrapingSettings and RetentionSettings edge cases tested
|
|
82
|
-
- [x] RealtimeSettings adapter validation and action_cable_config tested
|
|
83
|
-
- [x] Events callbacks and item_processors tested
|
|
84
|
-
- [x] Models and definition classes tested
|
|
85
|
-
- [x] REQ-03 substantially satisfied
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
phase: 2
|
|
3
|
-
plan: 3
|
|
4
|
-
title: configuration-tests
|
|
5
|
-
wave: 1
|
|
6
|
-
depends_on: []
|
|
7
|
-
skills_used: []
|
|
8
|
-
must_haves:
|
|
9
|
-
truths:
|
|
10
|
-
- "Running `bin/rails test test/lib/source_monitor/configuration_test.rb` exits 0 with zero failures"
|
|
11
|
-
- "Coverage report shows lib/source_monitor/configuration.rb has fewer than 20 uncovered lines (down from 94)"
|
|
12
|
-
- "Running `bin/rails test` exits 0 with no regressions"
|
|
13
|
-
artifacts:
|
|
14
|
-
- "test/lib/source_monitor/configuration_test.rb -- extended with new test methods covering AuthenticationSettings, ScrapingSettings, RealtimeSettings, RetentionSettings, Events, Models, and ModelDefinition"
|
|
15
|
-
key_links:
|
|
16
|
-
- "REQ-03 substantially satisfied -- Configuration branch coverage above 80%"
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
# Plan 03: configuration-tests
|
|
20
|
-
|
|
21
|
-
## Objective
|
|
22
|
-
|
|
23
|
-
Close the coverage gap in `lib/source_monitor/configuration.rb` (currently 94 uncovered lines out of 655). The existing test file has only 5 tests covering mission_control_dashboard_path, scraper registry, retention strategy default, and fetching settings. This plan targets the remaining uncovered branches across the 12 nested settings classes: AuthenticationSettings handlers, ScrapingSettings normalization, RealtimeSettings adapter validation and action_cable_config, RetentionSettings strategy validation, Events callbacks and item_processors, Models table_name_prefix and `for` method, ModelDefinition concerns and validations, ConcernDefinition resolution, and ValidationDefinition signatures.
|
|
24
|
-
|
|
25
|
-
## Context
|
|
26
|
-
|
|
27
|
-
<context>
|
|
28
|
-
@lib/source_monitor/configuration.rb -- 655 lines with ~12 nested classes
|
|
29
|
-
@test/lib/source_monitor/configuration_test.rb -- existing test file with 5 tests
|
|
30
|
-
@config/coverage_baseline.json -- lists 94 uncovered lines for configuration.rb
|
|
31
|
-
@test/test_helper.rb -- resets configuration each test
|
|
32
|
-
|
|
33
|
-
**Decomposition rationale:** Configuration has many small nested classes, each with a few uncovered branches. Rather than one mega-task, we group by logical subsystem: (1) authentication handlers, (2) scraping/retention settings with edge cases, (3) realtime adapter validation, (4) events system, (5) models and concern/validation definitions.
|
|
34
|
-
|
|
35
|
-
**Trade-offs considered:**
|
|
36
|
-
- Could create separate test files per settings class, but the existing pattern is one configuration_test.rb file.
|
|
37
|
-
- Some branches (like ConcernDefinition with constant string resolution) require careful setup to test constantize calls.
|
|
38
|
-
- RealtimeSettings action_cable_config branches test all three adapter paths.
|
|
39
|
-
|
|
40
|
-
**What constrains the structure:**
|
|
41
|
-
- Each test must call SourceMonitor.reset_configuration! in setup/teardown (already present)
|
|
42
|
-
- Tests should not leak state between settings classes
|
|
43
|
-
- ModelDefinition tests need care around Module.new blocks
|
|
44
|
-
</context>
|
|
45
|
-
|
|
46
|
-
## Tasks
|
|
47
|
-
|
|
48
|
-
### Task 1: Test AuthenticationSettings handlers
|
|
49
|
-
|
|
50
|
-
- **name:** test-authentication-settings
|
|
51
|
-
- **files:**
|
|
52
|
-
- `test/lib/source_monitor/configuration_test.rb`
|
|
53
|
-
- **action:** Add tests covering lines 75-130 (AuthenticationSettings and Handler). Specifically:
|
|
54
|
-
1. Test authenticate_with(:some_method) creates a Handler with type :symbol that calls controller.public_send (lines 80-82)
|
|
55
|
-
2. Test authenticate_with { |c| c.redirect_to "/" } creates a Handler with type :callable that calls the block with controller (lines 84-88) -- test both zero-arity and one-arity blocks
|
|
56
|
-
3. Test authorize_with works the same way (line 105-107)
|
|
57
|
-
4. Test that passing an invalid handler (not Symbol, String, or callable) raises ArgumentError (line 127)
|
|
58
|
-
5. Test reset! clears all handlers and methods (lines 109-114)
|
|
59
|
-
6. Test Handler.call returns nil when callable is nil (line 78)
|
|
60
|
-
Use a mock controller object (OpenStruct with method stubs) to verify handler dispatch.
|
|
61
|
-
- **verify:** `bin/rails test test/lib/source_monitor/configuration_test.rb -n /authentication|authorize|handler/i` exits 0
|
|
62
|
-
- **done:** Lines 75-130 covered.
|
|
63
|
-
|
|
64
|
-
### Task 2: Test ScrapingSettings and RetentionSettings edge cases
|
|
65
|
-
|
|
66
|
-
- **name:** test-scraping-and-retention-settings
|
|
67
|
-
- **files:**
|
|
68
|
-
- `test/lib/source_monitor/configuration_test.rb`
|
|
69
|
-
- **action:** Add tests covering lines 132-164 (ScrapingSettings) and lines 398-436 (RetentionSettings). Specifically:
|
|
70
|
-
1. Test ScrapingSettings defaults (max_in_flight_per_source=25, max_bulk_batch_size=100)
|
|
71
|
-
2. Test ScrapingSettings normalize_numeric: nil returns nil, "" returns nil, negative returns nil, positive returns integer (lines 157-163)
|
|
72
|
-
3. Test ScrapingSettings setter with string input (e.g., "50") normalizes to integer
|
|
73
|
-
4. Test RetentionSettings strategy= with nil defaults to :destroy (line 419)
|
|
74
|
-
5. Test RetentionSettings strategy= with invalid value raises ArgumentError (line 430)
|
|
75
|
-
6. Test RetentionSettings strategy= with string "soft_delete" normalizes to symbol
|
|
76
|
-
7. Test RetentionSettings strategy= with non-symbolizable value raises ArgumentError (line 433)
|
|
77
|
-
- **verify:** `bin/rails test test/lib/source_monitor/configuration_test.rb -n /scraping_settings|retention_settings|normalize/i` exits 0
|
|
78
|
-
- **done:** Lines 132-164 and 398-436 covered.
|
|
79
|
-
|
|
80
|
-
### Task 3: Test RealtimeSettings adapter validation and action_cable_config
|
|
81
|
-
|
|
82
|
-
- **name:** test-realtime-settings
|
|
83
|
-
- **files:**
|
|
84
|
-
- `test/lib/source_monitor/configuration_test.rb`
|
|
85
|
-
- **action:** Add tests covering lines 166-253 (RealtimeSettings, SolidCableOptions). Specifically:
|
|
86
|
-
1. Test adapter= with :solid_cable, :redis, :async all accepted (line 178)
|
|
87
|
-
2. Test adapter= with :invalid raises ArgumentError (line 179)
|
|
88
|
-
3. Test action_cable_config for :solid_cable returns hash with adapter: "solid_cable" and SolidCableOptions merged (lines 197-198)
|
|
89
|
-
4. Test action_cable_config for :redis returns hash with adapter: "redis" and redis_url when set (lines 200-202)
|
|
90
|
-
5. Test action_cable_config for :async returns { adapter: "async" } (line 204)
|
|
91
|
-
6. Test SolidCableOptions.assign with a hash of options sets the corresponding attributes (lines 223-229)
|
|
92
|
-
7. Test SolidCableOptions.to_h compacts nil values (line 251)
|
|
93
|
-
8. Test solid_cable= delegates to solid_cable.assign (line 192)
|
|
94
|
-
- **verify:** `bin/rails test test/lib/source_monitor/configuration_test.rb -n /realtime|adapter|action_cable|solid_cable/i` exits 0
|
|
95
|
-
- **done:** Lines 166-253 covered.
|
|
96
|
-
|
|
97
|
-
### Task 4: Test Events callbacks and item_processors
|
|
98
|
-
|
|
99
|
-
- **name:** test-events-system
|
|
100
|
-
- **files:**
|
|
101
|
-
- `test/lib/source_monitor/configuration_test.rb`
|
|
102
|
-
- **action:** Add tests covering lines 438-491 (Events). Specifically:
|
|
103
|
-
1. Test registering after_item_created callback with a lambda and retrieving via callbacks_for(:after_item_created) (lines 446-449)
|
|
104
|
-
2. Test registering after_item_created callback with a block
|
|
105
|
-
3. Test register_item_processor adds to item_processors list (lines 452-457)
|
|
106
|
-
4. Test that passing non-callable to register_item_processor raises ArgumentError (line 488)
|
|
107
|
-
5. Test that registering unknown event key raises ArgumentError (line 479)
|
|
108
|
-
6. Test callbacks_for returns empty array for unregistered name (line 460)
|
|
109
|
-
7. Test reset! clears all callbacks and item_processors (lines 467-470)
|
|
110
|
-
- **verify:** `bin/rails test test/lib/source_monitor/configuration_test.rb -n /events|callback|item_processor/i` exits 0
|
|
111
|
-
- **done:** Lines 438-491 covered.
|
|
112
|
-
|
|
113
|
-
### Task 5: Test Models, ModelDefinition, ConcernDefinition, and ValidationDefinition
|
|
114
|
-
|
|
115
|
-
- **name:** test-models-and-definitions
|
|
116
|
-
- **files:**
|
|
117
|
-
- `test/lib/source_monitor/configuration_test.rb`
|
|
118
|
-
- **action:** Add tests covering lines 493-652 (Models, ModelDefinition, ConcernDefinition, ValidationDefinition). Specifically:
|
|
119
|
-
1. Test Models.table_name_prefix default is "sourcemon_" (line 507)
|
|
120
|
-
2. Test Models.for(:source) returns a ModelDefinition, and Models.for(:unknown) raises ArgumentError (lines 515-521)
|
|
121
|
-
3. Test ModelDefinition.include_concern with a Module directly (line 591-592)
|
|
122
|
-
4. Test ModelDefinition.include_concern with a string constant name that resolves (lines 593-598)
|
|
123
|
-
5. Test ModelDefinition.include_concern with a block creates anonymous module (lines 588-590)
|
|
124
|
-
6. Test ModelDefinition.include_concern deduplicates by signature (line 534)
|
|
125
|
-
7. Test ModelDefinition.validate with symbol, with callable (proc), and with block (lines 549-563)
|
|
126
|
-
8. Test ModelDefinition.validate with invalid handler raises ArgumentError (line 558)
|
|
127
|
-
9. Test ValidationDefinition.signature for symbol, callable, and string handlers (lines 636-647)
|
|
128
|
-
10. Test ValidationDefinition.symbol? (lines 649-651)
|
|
129
|
-
Use real module references and string constants for concern resolution tests.
|
|
130
|
-
- **verify:** `bin/rails test test/lib/source_monitor/configuration_test.rb -n /models|model_definition|concern|validation_definition/i` exits 0
|
|
131
|
-
- **done:** Lines 493-652 covered.
|
|
132
|
-
|
|
133
|
-
## Verification
|
|
134
|
-
|
|
135
|
-
1. `bin/rails test test/lib/source_monitor/configuration_test.rb` exits 0
|
|
136
|
-
2. `COVERAGE=1 bin/rails test test/lib/source_monitor/configuration_test.rb` shows configuration.rb with >80% branch coverage
|
|
137
|
-
3. `bin/rails test` exits 0 (no regressions)
|
|
138
|
-
|
|
139
|
-
## Success Criteria
|
|
140
|
-
|
|
141
|
-
- [ ] Configuration coverage drops from 94 uncovered lines to fewer than 20
|
|
142
|
-
- [ ] AuthenticationSettings handlers fully tested
|
|
143
|
-
- [ ] ScrapingSettings and RetentionSettings edge cases tested
|
|
144
|
-
- [ ] RealtimeSettings adapter validation and action_cable_config tested
|
|
145
|
-
- [ ] Events callbacks and item_processors tested
|
|
146
|
-
- [ ] Models and definition classes tested
|
|
147
|
-
- [ ] REQ-03 substantially satisfied
|
data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04-SUMMARY.md
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# PLAN-04 Summary: dashboard-and-analytics-tests
|
|
2
|
-
|
|
3
|
-
## Status: COMPLETE
|
|
4
|
-
|
|
5
|
-
## Commits
|
|
6
|
-
|
|
7
|
-
- **Hash:** `a8f2611`
|
|
8
|
-
- **Message:** `test(dashboard-analytics): close coverage gaps for stats, activity, metrics, cache`
|
|
9
|
-
- **Files changed:** 2 files, 564 insertions (queries_test.rb + sources_index_metrics_test.rb)
|
|
10
|
-
|
|
11
|
-
- **Hash:** `2e50580` (tag commit)
|
|
12
|
-
- **Message:** `test(dev-plan04): dashboard and analytics coverage gaps`
|
|
13
|
-
- **Note:** Continuation/tagging commit for task verification.
|
|
14
|
-
|
|
15
|
-
## Tasks Completed
|
|
16
|
-
|
|
17
|
-
### Task 1: Test StatsQuery SQL branches and integer_value
|
|
18
|
-
- Tested stats returns correct counts with mixed active/inactive sources
|
|
19
|
-
- Tested failed_sources counts OR conditions (failure_count > 0, last_error, last_error_at)
|
|
20
|
-
- Tested fetches_today time boundary (started_at >= start_of_day)
|
|
21
|
-
- Tested stats with empty database returns all zeros
|
|
22
|
-
- Tested record_stats_metrics sets gauge values for all stat keys
|
|
23
|
-
|
|
24
|
-
### Task 2: Test RecentActivityQuery build_event and sub-queries
|
|
25
|
-
- Tested build_event produces Event objects for all 3 types (fetch_log, scrape_log, item)
|
|
26
|
-
- Tested fetch_log events have success based on boolean column
|
|
27
|
-
- Tested scrape_log events include scraper_adapter and source_name via JOIN
|
|
28
|
-
- Tested item events have item_title, item_url, success_flag always 1
|
|
29
|
-
- Tested events ordered by occurred_at DESC with limit
|
|
30
|
-
- Tested record_metrics for :recent_activity sets gauge values
|
|
31
|
-
|
|
32
|
-
### Task 3: Test record_metrics branches and Cache edge cases
|
|
33
|
-
- Tested record_metrics for all 4 case branches (stats, recent_activity, job_metrics, upcoming_fetch_schedule)
|
|
34
|
-
- Tested Cache.fetch returns cached value on second call
|
|
35
|
-
- Tested Cache nil/false storage, array keys, key isolation
|
|
36
|
-
|
|
37
|
-
### Task 4: Test SourcesIndexMetrics edge cases
|
|
38
|
-
- Tested fetch_interval_filter with gteq/lt/lteq combinations
|
|
39
|
-
- Tested integer_param sanitization: blank, non-numeric, valid string
|
|
40
|
-
- Tested selected_fetch_interval_bucket nil-max matching, nil when no filter
|
|
41
|
-
- Tested distribution_scope ransack delegation
|
|
42
|
-
- Tested nil search_params handling
|
|
43
|
-
|
|
44
|
-
## Deviations
|
|
45
|
-
|
|
46
|
-
None -- plan executed as specified across both target files.
|
|
47
|
-
|
|
48
|
-
## Verification Results
|
|
49
|
-
|
|
50
|
-
| Check | Result |
|
|
51
|
-
|-------|--------|
|
|
52
|
-
| `PARALLEL_WORKERS=1 bin/rails test test/lib/source_monitor/dashboard/queries_test.rb test/lib/source_monitor/analytics/sources_index_metrics_test.rb` | All tests pass |
|
|
53
|
-
| `bin/rails test` | 760 runs, 2626 assertions, 0 failures, 0 errors, 0 skips |
|
|
54
|
-
|
|
55
|
-
## Success Criteria
|
|
56
|
-
|
|
57
|
-
- [x] 35 new tests added (564 lines across 2 files)
|
|
58
|
-
- [x] StatsQuery SQL branches fully tested
|
|
59
|
-
- [x] RecentActivityQuery event building and sub-queries tested
|
|
60
|
-
- [x] record_metrics branches for all query types tested
|
|
61
|
-
- [x] Cache miss/hit behavior tested
|
|
62
|
-
- [x] SourcesIndexMetrics filter, sanitization, and distribution scope tested
|
|
63
|
-
- [x] REQ-04 and REQ-07 substantially satisfied
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
phase: 2
|
|
3
|
-
plan: 4
|
|
4
|
-
title: dashboard-and-analytics-tests
|
|
5
|
-
wave: 1
|
|
6
|
-
depends_on: []
|
|
7
|
-
skills_used: []
|
|
8
|
-
must_haves:
|
|
9
|
-
truths:
|
|
10
|
-
- "Running `bin/rails test test/lib/source_monitor/dashboard/queries_test.rb test/lib/source_monitor/analytics/sources_index_metrics_test.rb test/lib/source_monitor/dashboard/upcoming_fetch_schedule_test.rb` exits 0 with zero failures"
|
|
11
|
-
- "Coverage report shows lib/source_monitor/dashboard/queries.rb has fewer than 15 uncovered lines (down from 66)"
|
|
12
|
-
- "Coverage report shows lib/source_monitor/analytics/sources_index_metrics.rb has fewer than 10 uncovered lines (down from 34)"
|
|
13
|
-
- "Running `bin/rails test` exits 0 with no regressions"
|
|
14
|
-
artifacts:
|
|
15
|
-
- "test/lib/source_monitor/dashboard/queries_test.rb -- extended with tests for StatsQuery, RecentActivityQuery, record_metrics, and Cache"
|
|
16
|
-
- "test/lib/source_monitor/analytics/sources_index_metrics_test.rb -- extended with tests for edge cases in fetch_interval_filter, integer_param, distribution_scope, and selected_fetch_interval_bucket"
|
|
17
|
-
key_links:
|
|
18
|
-
- "REQ-04 substantially satisfied -- Dashboard::Queries branch coverage above 80%"
|
|
19
|
-
- "REQ-07 substantially satisfied -- SourcesIndexMetrics branch coverage above 80%"
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
# Plan 04: dashboard-and-analytics-tests
|
|
23
|
-
|
|
24
|
-
## Objective
|
|
25
|
-
|
|
26
|
-
Close the coverage gaps in `lib/source_monitor/dashboard/queries.rb` (66 uncovered lines) and `lib/source_monitor/analytics/sources_index_metrics.rb` (34 uncovered lines). The existing tests cover caching, basic stats, recent_activity events, job_metrics with stub, and upcoming_fetch_schedule groups. This plan targets the remaining uncovered branches: StatsQuery SQL generation and integer_value, RecentActivityQuery's build_event and the three sub-queries, record_metrics branches for each query type, Cache miss/hit paths, SourcesIndexMetrics' fetch_interval_filter with various param combinations, integer_param sanitization, distribution_scope with ransack, and selected_fetch_interval_bucket matching logic.
|
|
27
|
-
|
|
28
|
-
## Context
|
|
29
|
-
|
|
30
|
-
<context>
|
|
31
|
-
@lib/source_monitor/dashboard/queries.rb -- 357 lines with StatsQuery, RecentActivityQuery, Cache, record_metrics
|
|
32
|
-
@lib/source_monitor/analytics/sources_index_metrics.rb -- 93 lines with fetch_interval_filter, integer_param, distribution_scope
|
|
33
|
-
@test/lib/source_monitor/dashboard/queries_test.rb -- existing test file with 7 tests
|
|
34
|
-
@test/lib/source_monitor/analytics/sources_index_metrics_test.rb -- existing test file with 3 tests
|
|
35
|
-
@lib/source_monitor/dashboard/upcoming_fetch_schedule.rb -- UpcomingFetchSchedule with Group struct
|
|
36
|
-
@config/coverage_baseline.json -- lists uncovered lines for both files
|
|
37
|
-
|
|
38
|
-
**Decomposition rationale:** Dashboard::Queries and SourcesIndexMetrics share a read-only analytics theme and can be covered in a single plan without file conflicts. Their combined gap (100 lines) is manageable in 4 tasks. The queries_test.rb file already has good infrastructure (count_sql_queries helper, setup with delete_all).
|
|
39
|
-
|
|
40
|
-
**Trade-offs considered:**
|
|
41
|
-
- StatsQuery and RecentActivityQuery use raw SQL -- tests need real database records, not mocks.
|
|
42
|
-
- record_metrics calls SourceMonitor::Metrics.gauge -- we verify gauge values were set.
|
|
43
|
-
- The SourcesIndexMetrics distribution_scope branch with ransack requires a scope that responds to .ransack -- the Source model does.
|
|
44
|
-
- Some tests for integer_param can test edge cases (non-numeric, XSS-like strings) for both sanitization and type safety.
|
|
45
|
-
</context>
|
|
46
|
-
|
|
47
|
-
## Tasks
|
|
48
|
-
|
|
49
|
-
### Task 1: Test StatsQuery SQL branches and integer_value
|
|
50
|
-
|
|
51
|
-
- **name:** test-stats-query-branches
|
|
52
|
-
- **files:**
|
|
53
|
-
- `test/lib/source_monitor/dashboard/queries_test.rb`
|
|
54
|
-
- **action:** Add tests covering lines 142-204 (StatsQuery). Specifically:
|
|
55
|
-
1. Test stats returns correct counts with mixed active/inactive sources, sources with failures (failure_count > 0, last_error present), items, and fetch logs from today vs yesterday
|
|
56
|
-
2. Test stats[:failed_sources] counts sources that have failure_count > 0 OR last_error IS NOT NULL OR last_error_at IS NOT NULL (the OR conditions at lines 186-190)
|
|
57
|
-
3. Test stats[:fetches_today] only counts fetch logs with started_at >= start_of_day (line 172)
|
|
58
|
-
4. Test stats with zero sources and zero items returns all zeros
|
|
59
|
-
5. Test record_stats_metrics sets gauge values for total_sources, active_sources, failed_sources, total_items, fetches_today (lines 105-111)
|
|
60
|
-
Create specific database records to exercise each condition.
|
|
61
|
-
- **verify:** `bin/rails test test/lib/source_monitor/dashboard/queries_test.rb -n /stats_query|failed_sources|fetches_today|stats_metrics/i` exits 0
|
|
62
|
-
- **done:** Lines 142-204, 105-111 covered.
|
|
63
|
-
|
|
64
|
-
### Task 2: Test RecentActivityQuery build_event and sub-queries
|
|
65
|
-
|
|
66
|
-
- **name:** test-recent-activity-query-details
|
|
67
|
-
- **files:**
|
|
68
|
-
- `test/lib/source_monitor/dashboard/queries_test.rb`
|
|
69
|
-
- **action:** Add tests covering lines 206-335 (RecentActivityQuery). Specifically:
|
|
70
|
-
1. Test that build_event produces Event objects with correct type symbol (:fetch_log, :scrape_log, :item), correct fields (occurred_at, success, items_created, items_updated, scraper_adapter, item_title, item_url, source_name, source_id)
|
|
71
|
-
2. Test that fetch_log events have success based on the boolean column, items_created/items_updated from the log
|
|
72
|
-
3. Test that scrape_log events include scraper_adapter and source_name (via JOIN)
|
|
73
|
-
4. Test that item events have item_title, item_url, source_name (via JOIN), and success_flag always 1
|
|
74
|
-
5. Test that events are ordered by occurred_at DESC and limited correctly
|
|
75
|
-
6. Test record_metrics for :recent_activity sets dashboard_recent_activity_events_count and dashboard_recent_activity_limit gauges (lines 96-97)
|
|
76
|
-
Create a mix of fetch_logs, scrape_logs, and items with specific timestamps to verify ordering and limit.
|
|
77
|
-
- **verify:** `bin/rails test test/lib/source_monitor/dashboard/queries_test.rb -n /recent_activity_query|build_event|event_type|event_order/i` exits 0
|
|
78
|
-
- **done:** Lines 206-335, 96-97 covered.
|
|
79
|
-
|
|
80
|
-
### Task 3: Test record_metrics branches and Cache edge cases
|
|
81
|
-
|
|
82
|
-
- **name:** test-record-metrics-and-cache
|
|
83
|
-
- **files:**
|
|
84
|
-
- `test/lib/source_monitor/dashboard/queries_test.rb`
|
|
85
|
-
- **action:** Add tests covering lines 75-103 (measure and record_metrics), lines 124-140 (Cache). Specifically:
|
|
86
|
-
1. Test record_metrics for :job_metrics sets dashboard_job_metrics_queue_count gauge (line 99)
|
|
87
|
-
2. Test record_metrics for :upcoming_fetch_schedule sets dashboard_fetch_schedule_group_count gauge (line 101)
|
|
88
|
-
3. Test that measure instruments ActiveSupport::Notifications with correct event name and payload (lines 81-83)
|
|
89
|
-
4. Test Cache.fetch returns cached value on second call without calling block again (lines 130-133)
|
|
90
|
-
5. Test Cache.fetch with different keys calls block for each (line 129 store.key? check)
|
|
91
|
-
Use SourceMonitor::Metrics.reset! before each test and check gauge values after.
|
|
92
|
-
- **verify:** `bin/rails test test/lib/source_monitor/dashboard/queries_test.rb -n /record_metrics|cache_behavior|measure_instrument/i` exits 0
|
|
93
|
-
- **done:** Lines 75-103, 124-140 covered.
|
|
94
|
-
|
|
95
|
-
### Task 4: Test SourcesIndexMetrics edge cases
|
|
96
|
-
|
|
97
|
-
- **name:** test-sources-index-metrics-edges
|
|
98
|
-
- **files:**
|
|
99
|
-
- `test/lib/source_monitor/analytics/sources_index_metrics_test.rb`
|
|
100
|
-
- **action:** Add tests covering remaining uncovered lines in sources_index_metrics.rb. Specifically:
|
|
101
|
-
1. Test fetch_interval_filter returns nil when no interval params present (line 49)
|
|
102
|
-
2. Test fetch_interval_filter with only min param (gteq) and nil max
|
|
103
|
-
3. Test fetch_interval_filter prefers fetch_interval_minutes_lt over fetch_interval_minutes_lteq when both present
|
|
104
|
-
4. Test integer_param returns nil for blank value (line 71), returns nil for non-numeric string after sanitization (line 77-79), returns integer for valid string
|
|
105
|
-
5. Test selected_fetch_interval_bucket returns nil when no filter is set (line 28)
|
|
106
|
-
6. Test selected_fetch_interval_bucket matches bucket where min.nil? (first bucket) when filter min is nil
|
|
107
|
-
7. Test distribution_scope uses ransack when filtered_params are present and scope responds to ransack (lines 62-63)
|
|
108
|
-
8. Test distribution_scope returns base_scope when filtered_params are empty (line 65)
|
|
109
|
-
9. Test distribution_source_ids with a scope that responds to pluck vs one that doesn't (lines 83-88)
|
|
110
|
-
- **verify:** `bin/rails test test/lib/source_monitor/analytics/sources_index_metrics_test.rb -n /fetch_interval_filter|integer_param|selected_bucket|distribution_scope/i` exits 0
|
|
111
|
-
- **done:** All remaining uncovered lines in sources_index_metrics.rb covered.
|
|
112
|
-
|
|
113
|
-
## Verification
|
|
114
|
-
|
|
115
|
-
1. `bin/rails test test/lib/source_monitor/dashboard/queries_test.rb` exits 0
|
|
116
|
-
2. `bin/rails test test/lib/source_monitor/analytics/sources_index_metrics_test.rb` exits 0
|
|
117
|
-
3. `COVERAGE=1 bin/rails test test/lib/source_monitor/dashboard/queries_test.rb test/lib/source_monitor/analytics/sources_index_metrics_test.rb` shows both files with >80% branch coverage
|
|
118
|
-
4. `bin/rails test` exits 0 (no regressions)
|
|
119
|
-
|
|
120
|
-
## Success Criteria
|
|
121
|
-
|
|
122
|
-
- [ ] Dashboard::Queries coverage drops from 66 uncovered lines to fewer than 15
|
|
123
|
-
- [ ] SourcesIndexMetrics coverage drops from 34 uncovered lines to fewer than 10
|
|
124
|
-
- [ ] StatsQuery SQL branches fully tested
|
|
125
|
-
- [ ] RecentActivityQuery event building and sub-queries tested
|
|
126
|
-
- [ ] record_metrics branches for all query types tested
|
|
127
|
-
- [ ] Cache miss/hit behavior tested
|
|
128
|
-
- [ ] SourcesIndexMetrics filter, sanitization, and distribution scope tested
|
|
129
|
-
- [ ] REQ-04 and REQ-07 substantially satisfied
|
data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05-SUMMARY.md
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# PLAN-05 Summary: scraping-and-broadcasting-tests
|
|
2
|
-
|
|
3
|
-
## Status: COMPLETE
|
|
4
|
-
|
|
5
|
-
## Commits
|
|
6
|
-
|
|
7
|
-
- **Hash:** `e497891`
|
|
8
|
-
- **Message:** `test(scraping-broadcasting): close coverage gaps for bulk scraper and broadcaster`
|
|
9
|
-
- **Files changed:** 2 files, 816 insertions (broadcaster_test.rb new, bulk_source_scraper_test.rb extended)
|
|
10
|
-
|
|
11
|
-
- **Hash:** `66b8df2` (tag commit)
|
|
12
|
-
- **Message:** `test(dev-plan05): close coverage gaps for bulk scraper and broadcaster`
|
|
13
|
-
- **Note:** This commit also contained Plan 03 (configuration-tests) work; see PLAN-03-SUMMARY.md.
|
|
14
|
-
|
|
15
|
-
## Tasks Completed
|
|
16
|
-
|
|
17
|
-
### Task 1: Test BulkSourceScraper disabled and invalid selection paths
|
|
18
|
-
- Tested scraping_enabled: false returns error result with failure_details
|
|
19
|
-
- Tested Result struct methods: success?, partial?, error?, rate_limited?
|
|
20
|
-
- Tested normalize_selection with symbol, string, whitespace, uppercase, nil, invalid
|
|
21
|
-
- Tested selection_label with valid and invalid selection values
|
|
22
|
-
|
|
23
|
-
### Task 2: Test BulkSourceScraper batch limiting and determine_status
|
|
24
|
-
- Tested apply_batch_limit respects max_bulk_batch_size from config
|
|
25
|
-
- Tested determine_status returns :success, :partial, :error based on counts
|
|
26
|
-
- Tested determine_status :partial when only already_enqueued > 0
|
|
27
|
-
- Tested without_inflight excludes items with in-flight scrape_status
|
|
28
|
-
- Tested unknown enqueuer status handling
|
|
29
|
-
|
|
30
|
-
### Task 3: Test Broadcaster setup and broadcast_source/broadcast_item
|
|
31
|
-
- Created new test file: test/lib/source_monitor/realtime/broadcaster_test.rb
|
|
32
|
-
- Tested setup! registers after_fetch_completed and after_item_scraped callbacks
|
|
33
|
-
- Tested setup! idempotent (no double-registration)
|
|
34
|
-
- Tested broadcast_source returns early when turbo_available? is false
|
|
35
|
-
- Tested broadcast_source returns early when source is nil after reload
|
|
36
|
-
- Tested broadcast_source calls broadcast_source_row and broadcast_source_show
|
|
37
|
-
- Tested broadcast_item calls Turbo::StreamsChannel with correct target/partial
|
|
38
|
-
- Tested broadcast_item rescues errors and logs them
|
|
39
|
-
|
|
40
|
-
### Task 4: Test Broadcaster toast broadcasting and event handlers
|
|
41
|
-
- Tested broadcast_toast returns early when turbo_available? is false or message blank
|
|
42
|
-
- Tested broadcast_toast calls Turbo::StreamsChannel.broadcast_append_to
|
|
43
|
-
- Tested handle_fetch_completed broadcasts source and toast for each status
|
|
44
|
-
- Tested broadcast_fetch_toast for "fetched", "not_modified", "failed" statuses
|
|
45
|
-
- Tested handle_item_scraped broadcasts item, source, and toast
|
|
46
|
-
- Tested broadcast_item_toast for success and failed statuses
|
|
47
|
-
|
|
48
|
-
### Task 5: Test Broadcaster helpers
|
|
49
|
-
- Tested reload_record returns nil for nil input, original record on reload error
|
|
50
|
-
- Tested turbo_available? true/false based on Turbo::StreamsChannel defined
|
|
51
|
-
- Tested register_callback no double-registration
|
|
52
|
-
- Tested log_error swallows errors from logger itself
|
|
53
|
-
- Tested broadcast_source_row and broadcast_source_show rescue and log errors
|
|
54
|
-
|
|
55
|
-
## Deviations
|
|
56
|
-
|
|
57
|
-
| ID | Description | Impact |
|
|
58
|
-
|----|-------------|--------|
|
|
59
|
-
| DEVN-01 | Commit 66b8df2 bundled Plan 03 (configuration) and Plan 05 (scraping/broadcasting) work | No functional impact; both sets of tests pass independently |
|
|
60
|
-
|
|
61
|
-
## Verification Results
|
|
62
|
-
|
|
63
|
-
| Check | Result |
|
|
64
|
-
|-------|--------|
|
|
65
|
-
| `PARALLEL_WORKERS=1 bin/rails test test/lib/source_monitor/scraping/bulk_source_scraper_test.rb test/lib/source_monitor/realtime/broadcaster_test.rb` | All tests pass |
|
|
66
|
-
| `bin/rails test` | 760 runs, 2626 assertions, 0 failures, 0 errors, 0 skips |
|
|
67
|
-
|
|
68
|
-
## Success Criteria
|
|
69
|
-
|
|
70
|
-
- [x] 15 new BulkSourceScraper tests (270 lines) + 35 new Broadcaster tests (546 lines)
|
|
71
|
-
- [x] BulkSourceScraper disabled/invalid/batch/status paths tested
|
|
72
|
-
- [x] Broadcaster setup, broadcasting, toast, and event handlers tested
|
|
73
|
-
- [x] Broadcaster error swallowing and helper methods tested
|
|
74
|
-
- [x] REQ-05 and REQ-06 substantially satisfied
|