Module: Portage::Ucp::RSpec

Defined in:
lib/portage/ucp/rspec.rb

Overview

Adapter conformance kit — design-log §17: "Nothing currently checks a third-party Adapter against the contract before its capability shows up in a manifest." SchemaValidator (see README, "Spec conformance") checks wire shape; this checks the behavioral guarantees §9 promises that schema-valid output can still violate — idempotency not actually deduped, a raw PAN reaching the adapter, a capability advertised whose own output doesn't round-trip through the schema it claims to speak.

Not loaded by require "portage/ucp" — this pulls in RSpec itself, which the core gem otherwise has zero runtime dependency on (only a development one, per its own README). An adapter author's own spec suite opts in explicitly:

require "portage/ucp/rspec"

RSpec.describe MyAdapter do
it_behaves_like "a portage adapter" do
  let(:adapter) { MyAdapter.new(client: my_test_client) }
  let(:existing_product_id) { "known-good-product-id" }
  # optional — only needed when a purchasable line item is a
  # *different* id than the catalog product id (Shopify: a
  # ProductVariant GID vs. the parent Product GID). Defaults to
  # existing_product_id, which is correct for any backend where
  # "the product" and "the thing you add to a cart" share one id.
  # let(:existing_variant_id) { "known-good-purchasable-id" }
  # optional — enables the out-of-stock example:
  # let(:out_of_stock_product_id) { "known-sold-out-product-id" }
end
end

existing_product_id must resolve to a real, in-stock, purchasable product against whatever backend adapter is wired to (a live sandbox store, or webmock/VCR stubs — this kit doesn't care which). Every example below skips itself when the adapter under test doesn't advertise the capability it needs, so a catalog/cart-only adapter (§16's Etsy/Instagram shape) still runs the kit cleanly.

Class Method Summary collapse

Class Method Details

.advertised?(adapter, capability_name) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
# File 'lib/portage/ucp/rspec.rb', line 44

def advertised?(adapter, capability_name)
  capability = Portage::Ucp::CapabilityRegistry.default.find(capability_name)
  capability&.advertised_for?(adapter)
end