|
1 | 1 | import json |
2 | 2 |
|
| 3 | +import pytest |
| 4 | + |
3 | 5 | from agentscore_commerce.discovery import ( |
4 | 6 | BuildAgentScoreOpenApiSnippetsInput, |
5 | 7 | DiscoveryProbeOptions, |
@@ -152,3 +154,172 @@ def test_solana_only_no_base(self): |
152 | 154 | assert "### How to pay with x402 (Solana)" in section |
153 | 155 | assert "--chain solana" in section |
154 | 156 | assert "--chain base" not in section |
| 157 | + |
| 158 | + |
| 159 | +# ── sample_x402_accept_for_network: every registry branch ─────────────────── |
| 160 | + |
| 161 | + |
| 162 | +def test_sample_accept_base_mainnet() -> None: |
| 163 | + from agentscore_commerce.discovery.probe import sample_x402_accept_for_network |
| 164 | + |
| 165 | + e = sample_x402_accept_for_network("eip155:8453") |
| 166 | + assert e is not None |
| 167 | + assert e["network"] == "eip155:8453" |
| 168 | + assert e["scheme"] == "exact" |
| 169 | + assert e["extra"] == {"name": "USDC", "version": "2"} |
| 170 | + |
| 171 | + |
| 172 | +def test_sample_accept_base_sepolia() -> None: |
| 173 | + from agentscore_commerce.discovery.probe import sample_x402_accept_for_network |
| 174 | + |
| 175 | + e = sample_x402_accept_for_network("eip155:84532") |
| 176 | + assert e is not None |
| 177 | + assert e["network"] == "eip155:84532" |
| 178 | + |
| 179 | + |
| 180 | +def test_sample_accept_solana_mainnet() -> None: |
| 181 | + from agentscore_commerce.discovery.probe import sample_x402_accept_for_network |
| 182 | + |
| 183 | + e = sample_x402_accept_for_network("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp") |
| 184 | + assert e is not None |
| 185 | + assert "extra" not in e |
| 186 | + assert e["payTo"] == "11111111111111111111111111111111" |
| 187 | + |
| 188 | + |
| 189 | +def test_sample_accept_solana_devnet() -> None: |
| 190 | + from agentscore_commerce.discovery.probe import sample_x402_accept_for_network |
| 191 | + |
| 192 | + e = sample_x402_accept_for_network("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1") |
| 193 | + assert e is not None |
| 194 | + assert e["network"].startswith("solana:") |
| 195 | + |
| 196 | + |
| 197 | +def test_sample_accept_unknown_network_returns_none() -> None: |
| 198 | + from agentscore_commerce.discovery.probe import sample_x402_accept_for_network |
| 199 | + |
| 200 | + assert sample_x402_accept_for_network("eip155:1") is None |
| 201 | + |
| 202 | + |
| 203 | +# ── build_discovery_probe_response: x402 sample paths ─────────────────────── |
| 204 | + |
| 205 | + |
| 206 | +def _probe_opts(**overrides: object): |
| 207 | + from agentscore_commerce.discovery.probe import DiscoveryProbeOptions |
| 208 | + |
| 209 | + base: dict[str, object] = { |
| 210 | + "realm": "https://example.com", |
| 211 | + "sample_rail": "tempo-mainnet", |
| 212 | + "sample_amount_usd": 1.00, |
| 213 | + "sample_recipient": "0x0000000000000000000000000000000000000001", |
| 214 | + } |
| 215 | + base.update(overrides) |
| 216 | + return DiscoveryProbeOptions(**base) # type: ignore[arg-type] |
| 217 | + |
| 218 | + |
| 219 | +def test_probe_response_without_x402_sample() -> None: |
| 220 | + from agentscore_commerce.discovery.probe import build_discovery_probe_response |
| 221 | + |
| 222 | + resp = build_discovery_probe_response(_probe_opts()) |
| 223 | + assert resp.status == 402 |
| 224 | + assert "www-authenticate" in resp.headers |
| 225 | + assert "payment-required" not in resp.headers |
| 226 | + |
| 227 | + |
| 228 | +def test_probe_response_with_x402_sample_via_networks_shorthand() -> None: |
| 229 | + import json as _json |
| 230 | + |
| 231 | + from agentscore_commerce.discovery.probe import X402SampleProbe, build_discovery_probe_response |
| 232 | + |
| 233 | + resp = build_discovery_probe_response( |
| 234 | + _probe_opts(x402_sample=X402SampleProbe(networks=["eip155:84532", "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"])) |
| 235 | + ) |
| 236 | + assert resp.status == 402 |
| 237 | + assert "payment-required" in resp.headers |
| 238 | + body = _json.loads(resp.body) |
| 239 | + assert body["x402Version"] == 2 |
| 240 | + assert len(body["accepts"]) == 2 |
| 241 | + |
| 242 | + |
| 243 | +def test_probe_response_with_explicit_accepts_overrides_networks_shorthand() -> None: |
| 244 | + import json as _json |
| 245 | + |
| 246 | + from agentscore_commerce.discovery.probe import X402SampleProbe, build_discovery_probe_response |
| 247 | + |
| 248 | + custom = [{"scheme": "exact", "network": "fake", "asset": "X", "payTo": "Y"}] |
| 249 | + resp = build_discovery_probe_response(_probe_opts(x402_sample=X402SampleProbe(accepts=custom, version=1))) |
| 250 | + body = _json.loads(resp.body) |
| 251 | + assert body["x402Version"] == 1 |
| 252 | + assert body["accepts"][0]["network"] == "fake" |
| 253 | + |
| 254 | + |
| 255 | +def test_probe_response_with_resource_url() -> None: |
| 256 | + import base64 |
| 257 | + import json as _json |
| 258 | + |
| 259 | + from agentscore_commerce.discovery.probe import X402SampleProbe, build_discovery_probe_response |
| 260 | + |
| 261 | + resp = build_discovery_probe_response( |
| 262 | + _probe_opts(x402_sample=X402SampleProbe(networks=["eip155:84532"], resource_url="https://example.com/api")) |
| 263 | + ) |
| 264 | + decoded = _json.loads(base64.b64decode(resp.headers["payment-required"]).decode()) |
| 265 | + assert decoded["resource"]["url"] == "https://example.com/api" |
| 266 | + |
| 267 | + |
| 268 | +def test_probe_response_with_docs_url() -> None: |
| 269 | + import json as _json |
| 270 | + |
| 271 | + from agentscore_commerce.discovery.probe import build_discovery_probe_response |
| 272 | + |
| 273 | + resp = build_discovery_probe_response(_probe_opts(docs_url="https://docs.example.com")) |
| 274 | + body = _json.loads(resp.body) |
| 275 | + assert body["docs"] == "https://docs.example.com" |
| 276 | + |
| 277 | + |
| 278 | +def test_probe_response_unknown_network_filtered_out() -> None: |
| 279 | + import json as _json |
| 280 | + |
| 281 | + from agentscore_commerce.discovery.probe import X402SampleProbe, build_discovery_probe_response |
| 282 | + |
| 283 | + resp = build_discovery_probe_response( |
| 284 | + _probe_opts(x402_sample=X402SampleProbe(networks=["eip155:84532", "eip155:99999"])) |
| 285 | + ) |
| 286 | + body = _json.loads(resp.body) |
| 287 | + assert len(body["accepts"]) == 1 |
| 288 | + |
| 289 | + |
| 290 | +# ── is_discovery_probe_request ────────────────────────────────────────────── |
| 291 | + |
| 292 | + |
| 293 | +@pytest.mark.asyncio |
| 294 | +async def test_is_probe_empty_post() -> None: |
| 295 | + from agentscore_commerce.discovery.probe import is_discovery_probe_request |
| 296 | + |
| 297 | + assert await is_discovery_probe_request("POST", None, "") is True |
| 298 | + |
| 299 | + |
| 300 | +@pytest.mark.asyncio |
| 301 | +async def test_is_probe_empty_object_post() -> None: |
| 302 | + from agentscore_commerce.discovery.probe import is_discovery_probe_request |
| 303 | + |
| 304 | + assert await is_discovery_probe_request("POST", None, "{}") is True |
| 305 | + |
| 306 | + |
| 307 | +@pytest.mark.asyncio |
| 308 | +async def test_is_probe_non_post_rejected() -> None: |
| 309 | + from agentscore_commerce.discovery.probe import is_discovery_probe_request |
| 310 | + |
| 311 | + assert await is_discovery_probe_request("GET", None, "") is False |
| 312 | + |
| 313 | + |
| 314 | +@pytest.mark.asyncio |
| 315 | +async def test_is_probe_with_payment_authz_rejected() -> None: |
| 316 | + from agentscore_commerce.discovery.probe import is_discovery_probe_request |
| 317 | + |
| 318 | + assert await is_discovery_probe_request("POST", "Payment foo", "") is False |
| 319 | + |
| 320 | + |
| 321 | +@pytest.mark.asyncio |
| 322 | +async def test_is_probe_with_real_body_rejected() -> None: |
| 323 | + from agentscore_commerce.discovery.probe import is_discovery_probe_request |
| 324 | + |
| 325 | + assert await is_discovery_probe_request("POST", None, '{"product": "x"}') is False |
0 commit comments