Module: DevDoc::Test::Lints::ExternalIoBoundary
- Defined in:
- lib/dev_doc/test/lints/external_io_boundary.rb
Overview
External-I/O boundary tripwire: HTTP-client code must live only in
app/services/ adapters.
Rationale
External-I/O sequencing (requests, retries, provider fallback,
pagination) is the one kind of orchestration whose home is
app/services/ — see best_practices/backend/en/12_orchestration.md.
DevDoc/Rails/NoPersistenceInService enforces the inward half of that
boundary (adapters cannot persist or enqueue); this lint enforces the
outward half: no HTTP client leaks into models, controllers, jobs, or
views, where it would be unmockable, untracked, and invisible to the
adapter conventions. A tripwire rather than a cop because it guards an
invariant that currently holds — there is nothing for a cop's
observed-violation justification gate to measure.
NOTE: Limitations:
- Matching is textual (per line, comments stripped) over
app/**/*.rbonly — an HTTP call assembled viaObject.const_getor made fromlib/is invisible. - Only the generic Ruby HTTP clients are in the default token list;
add each provider SDK your project uses (e.g.
Stripe) via the per-project override.
Usage
Include this module in a Minitest test class (Rails test env). To extend the token list or exempt a sanctioned path, redefine the constants on the test class:
class ExternalIoBoundaryTest < ActiveSupport::TestCase
include DevDoc::Test::Lints::ExternalIoBoundary
# HTTP_CLIENT_TOKENS =
# (ExternalIoBoundaryChecker::DEFAULT_HTTP_CLIENT_TOKENS + %w[Stripe]).freeze
# ALLOWED_EXTERNAL_IO_PATHS = %w[app/middleware/proxy.rb].freeze
end
Constant Summary collapse
- HTTP_CLIENT_TOKENS =
Defaults. Per-project override: redefine the constants on the test class that includes this module.
ExternalIoBoundaryChecker::DEFAULT_HTTP_CLIENT_TOKENS
- ALLOWED_EXTERNAL_IO_PATHS =
[].freeze
Instance Method Summary collapse
Instance Method Details
#test_no_http_clients_outside_app_services ⇒ Object
109 110 111 112 113 114 115 116 117 |
# File 'lib/dev_doc/test/lints/external_io_boundary.rb', line 109 def test_no_http_clients_outside_app_services offenders = ExternalIoBoundaryChecker.new( Rails.root, tokens: self.class::HTTP_CLIENT_TOKENS, allowed_paths: self.class::ALLOWED_EXTERNAL_IO_PATHS ).offenders assert offenders.empty?, (offenders) end |