feat: affiliates disclosure — per-retailer tooltip copy + first-encounter banner constants

This commit is contained in:
pyr0ball 2026-04-04 18:14:58 -07:00
parent 4c3f3a95a5
commit 73cec07bd2
2 changed files with 78 additions and 0 deletions

View file

@ -0,0 +1,49 @@
"""Affiliate disclosure copy constants.
Follows the plain-language disclosure design from the affiliate links design
doc. All copy is centralized here so products don't drift out of sync and
legal/copy review has a single file to audit.
"""
from __future__ import annotations
# Per-retailer tooltip copy (shown on hover/tap of affiliate link indicator)
_TOOLTIP: dict[str, str] = {
"ebay": (
"Affiliate link — CircuitForge earns a small commission if you purchase "
"on eBay. No purchase data is shared with us. [Opt out in Settings]"
),
"amazon": (
"Affiliate link — CircuitForge earns a small commission if you purchase "
"on Amazon. No purchase data is shared with us. [Opt out in Settings]"
),
}
_GENERIC_TOOLTIP = (
"Affiliate link — CircuitForge may earn a small commission if you purchase. "
"No purchase data is shared with us. [Opt out in Settings]"
)
# First-encounter banner copy (shown once, then preference saved)
BANNER_COPY: dict[str, str] = {
"title": "A note on purchase links",
"body": (
"Some links in this product go to retailers using our affiliate code. "
"When you click one, the retailer knows you came from CircuitForge. "
"We don't see or store what you buy. The retailer may track your "
"purchase — that's between you and them.\n\n"
"If you'd rather use plain links with no tracking code, you can opt "
"out in Settings."
),
"dismiss_label": "Got it",
"opt_out_label": "Opt out now",
"learn_more_label": "Learn more",
}
def get_disclosure_text(retailer: str) -> str:
"""Return the tooltip disclosure string for *retailer*.
Falls back to a generic string for unregistered retailers so callers
never receive an empty string.
"""
return _TOOLTIP.get(retailer, _GENERIC_TOOLTIP)

View file

@ -0,0 +1,29 @@
"""Tests for affiliate disclosure text."""
import pytest
from circuitforge_core.affiliates.disclosure import get_disclosure_text, BANNER_COPY
class TestGetDisclosureText:
def test_returns_string_for_known_retailer(self):
text = get_disclosure_text("ebay")
assert isinstance(text, str)
assert len(text) > 0
def test_ebay_copy_mentions_ebay(self):
text = get_disclosure_text("ebay")
assert "eBay" in text
def test_amazon_copy_mentions_amazon(self):
text = get_disclosure_text("amazon")
assert "Amazon" in text
def test_unknown_retailer_returns_generic(self):
text = get_disclosure_text("not_a_retailer")
assert isinstance(text, str)
assert len(text) > 0
def test_banner_copy_has_required_keys(self):
assert "title" in BANNER_COPY
assert "body" in BANNER_COPY
assert "opt_out_label" in BANNER_COPY
assert "dismiss_label" in BANNER_COPY