PrintMaster Test Coverage Analysis
Last Updated: December 27, 2025
This document provides a comprehensive analysis of test coverage across the PrintMaster codebase, identifying well-tested areas, gaps, and recommendations for improvement.
Executive Summary
| Component | Test Files | Coverage Level | Priority for Improvement |
|---|---|---|---|
| Server Storage | 20+ | ⭐⭐⭐⭐⭐ Excellent | Low |
| Agent Scanner | 8 | ⭐⭐⭐⭐ Good | Medium |
| Common Libraries | 12 | ⭐⭐⭐⭐ Good | Low |
| Server API/Handlers | 3 | ⭐⭐⭐ Moderate | Medium |
| Agent Storage | 6 | ⭐⭐⭐⭐ Good | Low |
| Reports System | 3 | ⭐⭐⭐ Moderate | Medium |
| WebSocket/Proxy | 2 | ⭐⭐⭐ Moderate | Medium |
| E2E Tests | 3 | ⭐⭐ Basic | HIGH |
| Email Templates | 0 | ⭐ None | HIGH |
| Spooler (Windows) | 0 | ⭐ None | HIGH |
| Metrics Collector | 0 | ⭐ None | HIGH |
| Report Scheduler | 0 | ⭐ None | HIGH |
| OIDC Handlers | 0 | ⭐ None | Medium |
| JS/Frontend | 14 | ⭐⭐⭐ Moderate | Medium |
1. Go Unit Tests (92 test files)
1.1 Server Package (server/)
✅ Excellent Coverage
| File/Package | Tests | Description |
|---|---|---|
storage/*_test.go | 20+ files | Most comprehensive testing - Covers all CRUD operations, agents, devices, metrics, alerts, reports, users, sessions, tenants, settings, OIDC, dialects |
main_test.go | 30+ tests | Health endpoints, auth, heartbeat, batch uploads, token handling, device proxy parsing |
config_test.go | Multiple | Configuration loading/parsing |
websocket_test.go | 8+ tests | WebSocket connection, heartbeat, proxy requests |
Key storage tests:
base_store_test.go- Agent lifecycle, device lifecycle, metrics, tenants, sites, audit logalerts_test.go/alerts_extended_test.go- Alert lifecycle, filters, notificationsreports_test.go/reports_extended_test.go- Report definitions, schedules, runs, cleanupusers_test.go- User CRUD, authentication, password updatessettings_test.go/settings_extended_test.go- Global/tenant settings, fleet policiesdialect_test.go- SQLite and Postgres SQL generation
⚠️ Moderate Coverage
| File/Package | Tests | Gaps |
|---|---|---|
alerts/ | 2 files | evaluator_test.go, notifier_test.go - Good but no integration tests |
reports/ | 2 files | formatter_test.go, generator_test.go - Missing scheduler tests |
releases/ | 3 files | API, manager, intake worker |
selfupdate/ | 2 files | detect, manager |
settings/ | 2 files | API, agent payload |
tenancy/ | 2 files | handlers, store |
authz/ | 1 file | Authorization logic |
updatepolicy/ | 1 file | Update policy API |
❌ No Test Coverage
| File/Package | Lines | Priority | Notes |
|---|---|---|---|
email/templates.go | 1153 | HIGH | Email generation for alerts, reports, password reset - zero tests |
metrics/collector.go | 419 | HIGH | Server metrics collection worker - zero tests |
reports/scheduler.go | 409 | HIGH | Report scheduling - zero tests |
websocket.go | 602 | Medium | Some coverage in websocket_test.go but many untested paths |
oidc_handlers.go | ~300+ | Medium | OIDC SSO handlers |
tls.go | ~100 | Low | TLS configuration |
device_auth.go | ~150 | Medium | Device authentication |
logging_helpers.go | ~50 | Low | Helper functions |
api_reports.go | ~200 | Medium | Report API endpoints |
1.2 Agent Package (agent/)
✅ Excellent Coverage
| File/Package | Tests | Description |
|---|---|---|
scanner/ | 8 files | Pipeline, detector, query, SNMP batch, capabilities |
scanner/vendor/ | 4 files | Epson, HP, Kyocera parsing, vendor detection |
scanner/capabilities/ | 1 file | Device capability detection (color, mono, MFP) |
storage/ | 6 files | SQLite operations, rotation, downsampling, scan history, paths |
agent/ (subpkg) | 5 files | Range parser, probe, parse, server client, WebSocket client |
Key scanner tests:
pipeline_test.go- Liveness/detection pool orchestrationdetector_test.go- Saved device bypass, SNMP detection, deep scan, enrichmentquery_test.go- Query profiles (minimal, essential, metrics, full), vendor walksvendor_test.go- Vendor detection, enterprise number extraction, supply colorscapabilities_test.go- 14+ tests for printer/color/mono detection, metric relevance
Key storage tests:
sqlite_test.go- 14+ tests for CRUD, atomic transactions, metrics rulesrotation_test.go- Database rotation, backup cleanupscan_history_test.go- Scan history tracking, visibility filteringdownsample_test.go- Metrics downsampling
⚠️ Moderate Coverage
| File/Package | Tests | Gaps |
|---|---|---|
config_test.go | Yes | Basic config loading |
config_store_test.go | Yes | Config store operations |
upload_worker_test.go | 2 tests | Only heartbeat settings handling tested |
settings_manager_test.go | Yes | Settings management |
update_policy_test.go | 5 tests | Policy precedence logic |
service_test.go | Yes | Service control |
server_probe_test.go | Yes | Server connectivity probing |
server_config_test.go | Yes | Server configuration |
autoupdate/manager_test.go | Yes | Auto-update manager |
featureflags/ | 1 file | Feature flag parsing |
proxy/vendor_login_test.go | Yes | Vendor-specific login handling |
supplies/normalize_test.go | Yes | Supply description normalization |
❌ No Test Coverage
| File/Package | Lines | Priority | Notes |
|---|---|---|---|
spooler/* | ~200+ | HIGH | Windows print spooler monitoring - zero tests |
autoupdate_worker.go | ~300 | Medium | Auto-update orchestration |
spooler_worker.go | ~200 | Medium | Spooler background worker |
discover.go | ~200 | Medium | Main discovery orchestration (tested indirectly) |
main.go | ~800+ | Medium | Application bootstrap (difficult to unit test) |
scanner_api.go | ~150 | Low | Scanner HTTP API handlers |
1.3 Common Package (common/)
✅ Good Coverage
| File/Package | Tests | Description |
|---|---|---|
logger/logger_test.go | 12+ tests | Log levels, context, circular buffer, file output, rate limiting, rotation, concurrency |
ws/ | 3 files | Message serialization, hub register/unregister/broadcast, connection nil-safety |
settings/types_test.go | 3 tests | Default settings, sanitization, schema validation |
storage/types_test.go | 5 tests | Device/metrics JSON round-trip, field locks, filters |
updatepolicy/types_test.go | 8 tests | Version pin, agent override, policy JSON, maintenance windows |
config/config_test.go | Yes | Configuration parsing |
snmp/oids/oids_test.go | 3 tests | OID format validation, uniqueness, MIB prefixes |
util/helpers_test.go | 4 tests | Octet string decoding, integer coercion |
util/secret_test.go | 2 tests | Encryption round-trip, key validation |
2. JavaScript Tests (14 test files)
2.1 Unit Tests (common/web/__tests__/)
| Test File | Coverage | Description |
|---|---|---|
formatters.test.js | ⭐⭐⭐ | Date/number formatting utilities |
debounce.test.js | ⭐⭐⭐ | Debounce function |
clipboard.test.js | ⭐⭐⭐ | Clipboard operations |
dom-shims.test.js | ⭐⭐⭐ | DOM compatibility shims |
rbac.test.js | ⭐⭐⭐ | Role-based access control |
save-device.test.js | ⭐⭐⭐ | Device save operations |
settings-save.test.js | ⭐⭐⭐ | Settings persistence |
server/web/__tests__/login-page.test.js | ⭐⭐ | Login page functionality |
2.2 Playwright E2E Tests (common/web/__tests__/playwright/)
| Test File | Coverage | Description |
|---|---|---|
smoke.test.js | ⭐⭐ | Toast notifications, confirm modals |
login.test.js | ⭐⭐ | Login flow |
sites-api.test.js | ⭐⭐ | Sites API |
reports-api.test.js | ⭐⭐ | Reports API |
alerting-api.test.js | ⭐⭐ | Alerting API |
tenancy-tabs.test.js | ⭐⭐ | Multi-tenancy UI |
3. Integration/E2E Tests (tests/)
| Test File | Status | Description |
|---|---|---|
websocket_proxy_test.go | ⭐⭐⭐ | WebSocket proxy flow, unreachable targets - 432 lines |
http_api_test.go | ⭐⭐⭐ | Agent registration, heartbeat - 314 lines |
E2E_TESTING.md | 📄 | Strategy document (tests WIP) |
Current E2E Limitations:
- Tests use mock servers, not actual binaries
- No real agent-server integration tests running in CI
- Process management helpers not fully implemented
4. Critical Gaps Analysis
🔴 HIGH Priority (No Tests)
1. Email Templates (server/email/templates.go - 1153 lines)
Risk: Email rendering bugs affect user experience for alerts, reports, password resets Recommendation:
// Suggested tests:
- TestRenderAlertEmail_AllSeverities
- TestRenderReportEmail_AllFormats
- TestRenderPasswordResetEmail
- TestRenderInvitationEmail
- TestThemeVariants_DarkLightAuto
- TestEmailHTMLValidation
2. Metrics Collector (server/metrics/collector.go - 419 lines)
Risk: Fleet monitoring data could be incorrect or missing Recommendation:
// Suggested tests:
- TestCollector_FleetDataCollection
- TestCollector_AggregationCycle
- TestCollector_PruneCycle
- TestCollector_ConcurrentAccess
- TestCollector_ErrorRecovery
3. Report Scheduler (server/reports/scheduler.go - 409 lines)
Risk: Scheduled reports might not run or fail silently Recommendation:
// Suggested tests:
- TestScheduler_RunsDueReports
- TestScheduler_HandlesFailures
- TestScheduler_CalculatesNextRun
- TestScheduler_StartStop
- TestScheduler_ConcurrentSchedules
4. Windows Spooler (agent/spooler/ - ~200+ lines)
Risk: USB printer discovery broken on Windows Recommendation:
// Suggested tests (with mock Windows APIs):
- TestDiscoverLocalPrinters_Windows
- TestParsePortName
- TestClassifyPrinterType
- TestJobWatcher_Events
🟡 MEDIUM Priority
5. Upload Worker (agent/upload_worker.go)
Current: Only 2 tests for heartbeat settings Missing:
- Device batch upload logic
- Metrics batch upload logic
- Retry/backoff behavior
- Error handling paths
6. WebSocket Full Coverage (server/websocket.go - 602 lines)
Current: 8 tests cover basic flows Missing:
- Proxy timeout handling
- Connection loss recovery
- Concurrent request handling
- Agent reconnection logic
7. OIDC Handlers (server/oidc_handlers.go)
Risk: SSO authentication failures Missing:
- OAuth flow tests
- Token validation
- Provider configuration
- Session linking
5. Test Quality Observations
✅ Strengths
- Storage layer is exemplary - Comprehensive CRUD tests, edge cases, multiple dialects
- Scanner uses dependency injection - MockSNMP pattern enables thorough unit testing
- Table-driven tests - Many tests use idiomatic Go patterns
- Parallel execution - Most tests use
t.Parallel()for speed - In-memory databases - Storage tests use
:memory:for isolation
⚠️ Areas for Improvement
- Missing negative tests - Many packages lack error-path testing
- No fuzz testing - Parser/deserializer code could benefit from fuzzing
- Limited concurrency tests - Race conditions not systematically tested
- No benchmark tests - Performance baselines not established
- E2E tests incomplete -
tests/directory has skeleton but not CI-integrated
6. Recommendations
Immediate Actions (Next Sprint)
Add email template tests (1153 lines untested)
- Create
server/email/templates_test.go - Test each email type renders without error
- Validate HTML structure
- Create
Add metrics collector tests (419 lines untested)
- Create
server/metrics/collector_test.go - Mock store interface
- Test collection/aggregation cycles
- Create
Add report scheduler tests (409 lines untested)
- Create
server/reports/scheduler_test.go - Test schedule processing
- Test failure handling
- Create
Short-term (Next Month)
Expand upload worker tests
- Add batch upload tests
- Test retry logic
- Test error scenarios
Complete E2E test infrastructure
- Implement process management helpers
- Add to CI pipeline
- Test critical paths (registration → heartbeat → upload)
Add OIDC handler tests
- Mock OAuth providers
- Test authentication flows
Long-term (Quarterly)
- Add benchmark tests for performance-critical paths
- Add fuzz tests for parsers (SNMP, vendor-specific)
- Improve coverage metrics - Set up coverage reporting in CI
7. Test Commands Reference
# Run all agent tests
cd agent && go test ./... -v
# Run all server tests
cd server && go test ./... -v
# Run specific package tests
cd agent/scanner && go test -v
# Run tests with coverage
go test ./... -coverprofile=coverage.out
go tool cover -html=coverage.out
# Run short tests only (skip E2E)
go test -short ./...
# Run E2E tests
cd tests && go test -v ./...
# Run JavaScript tests
npm test
# Run Playwright E2E tests
npm run test:e2e
8. Coverage by Lines of Code (Estimated)
| Component | Total LOC | Tested LOC | Coverage % |
|---|---|---|---|
| Server Storage | ~8,000 | ~7,500 | ~94% |
| Agent Scanner | ~3,000 | ~2,500 | ~83% |
| Agent Storage | ~2,000 | ~1,800 | ~90% |
| Common Libs | ~2,000 | ~1,600 | ~80% |
| Server Main/API | ~3,000 | ~1,500 | ~50% |
| Untested Files | |||
| - email/templates | 1,153 | 0 | 0% |
| - metrics/collector | 419 | 0 | 0% |
| - reports/scheduler | 409 | 0 | 0% |
| - spooler/* | ~400 | 0 | 0% |
Appendix: Test File Inventory
All 92 Go Test Files
Agent (33 files)
agent/config_store_test.goagent/config_test.goagent/health_test.goagent/main_settings_test.goagent/server_config_test.goagent/server_probe_test.goagent/service_test.goagent/settings_manager_test.goagent/update_policy_test.goagent/upload_worker_test.goagent/agent/parse_test.goagent/agent/probe_test.goagent/agent/rangeparser_test.goagent/agent/server_client_test.goagent/agent/snmp_performance_test.goagent/agent/ws_client_test.goagent/autoupdate/manager_test.goagent/featureflags/featureflags_test.goagent/proxy/vendor_login_test.goagent/scanner/capabilities/capabilities_test.goagent/scanner/detector_test.goagent/scanner/pipeline_test.goagent/scanner/query_test.goagent/scanner/snmp_batch_test.goagent/scanner/vendor/epson_remote_test.goagent/scanner/vendor/epson_st2_parser_test.goagent/scanner/vendor/vendor_test.goagent/storage/downsample_test.goagent/storage/paths_test.goagent/storage/rotation_integration_test.goagent/storage/rotation_test.goagent/storage/scan_history_test.goagent/storage/sqlite_test.goagent/supplies/normalize_test.go
Server (37 files)
server/config_test.goserver/main_test.goserver/injection_test.goserver/static_test.goserver/testutil_test.goserver/websocket_test.goserver/auth_ratelimit_test.goserver/rbac_handlers_test.goserver/alerts/evaluator_test.goserver/alerts/notifier_test.goserver/authz/authz_test.goserver/internal/db/driver_test.goserver/logger/logger_test.goserver/releases/api_test.goserver/releases/intake_worker_test.goserver/releases/manager_test.goserver/reports/formatter_test.goserver/reports/generator_test.goserver/selfupdate/detect_test.goserver/selfupdate/manager_test.goserver/settings/agent_payload_test.goserver/settings/api_test.goserver/storage/aggregated_metrics_test.goserver/storage/alerts_extended_test.goserver/storage/alerts_test.goserver/storage/base_store_extended_test.goserver/storage/base_store_test.goserver/storage/dialect_extended_test.goserver/storage/dialect_test.goserver/storage/helpers_test.goserver/storage/oidc_test.goserver/storage/postgres_integration_test.goserver/storage/release_artifacts_test.goserver/storage/reports_extended_test.goserver/storage/reports_test.goserver/storage/selfupdate_runs_test.goserver/storage/settings_extended_test.goserver/storage/settings_test.goserver/storage/sqlite_sessions_test.goserver/storage/store_test.goserver/storage/types_test.goserver/storage/users_test.goserver/tenancy/handlers_test.goserver/tenancy/store_test.goserver/updatepolicy/api_test.go
Common (12 files)
common/config/config_test.gocommon/logger/logger_test.gocommon/settings/types_test.gocommon/snmp/oids/oids_test.gocommon/storage/types_test.gocommon/updatepolicy/types_test.gocommon/util/helpers_test.gocommon/util/secret_test.gocommon/ws/conn_test.gocommon/ws/hub_test.gocommon/ws/message_test.go
Integration/E2E (2 files)
tests/http_api_test.gotests/websocket_proxy_test.go
All 14 JavaScript Test Files
Unit Tests
common/web/__tests__/clipboard.test.jscommon/web/__tests__/debounce.test.jscommon/web/__tests__/dom-shims.test.jscommon/web/__tests__/formatters.test.jscommon/web/__tests__/rbac.test.jscommon/web/__tests__/save-device.test.jscommon/web/__tests__/settings-save.test.jsserver/web/__tests__/login-page.test.js
Playwright E2E Tests
common/web/__tests__/playwright/alerting-api.test.jscommon/web/__tests__/playwright/login.test.jscommon/web/__tests__/playwright/reports-api.test.jscommon/web/__tests__/playwright/sites-api.test.jscommon/web/__tests__/playwright/smoke.test.jscommon/web/__tests__/playwright/tenancy-tabs.test.js