fix(humanitix): upgrade SDK to v2.0.0, add unit and integration tests (#304)#306
fix(humanitix): upgrade SDK to v2.0.0, add unit and integration tests (#304)#306Shubhank-Jonnada wants to merge 6 commits intomasterfrom
Conversation
…n.load()
- Fix humanitix.py to use Integration.load("config.json") so the config
is resolved relative to cwd (required for multi-file integrations with
an actions/ sub-package, per SDK documentation)
- Delete the old manual test script (tests/test_humanitix.py)
- Add tests/conftest.py for pytest path resolution
- Add tests/test_humanitix_unit.py: 33 unit tests covering all 6 actions
(get_events, get_orders, get_tickets, get_tags, check_in, check_out)
using AsyncMock for context.fetch
- Add tests/test_humanitix_integration.py: live integration tests for
read-only actions (get_events, get_tags) that skip if HUMANITIX_API_KEY
is not set
… ActionError for errors
… use Integration.load()
🔍 Integration Validation ResultsCommit: Changed directories:
✅ Structure Check output✅ Code Check output✅ Tests Check output✅ README Check output✅ Version Check output |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e3a923360
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…to avoid AttributeError
|
@TheRealAgentK integration tests are blocked locally by Cloudflare, Humanitix's API returns a 403 from any server-side or datacenter IP. Unit tests all pass (32/32) and validation is clean, but we can't run live integration tests in CI or locally without a residential/browser IP. Wanted to flag this and get your thoughts on how you want to handle it before we move forward. |
|
Just to clarify - you're saying we couldn't run e-2-e CI from GH for instance, correct? That'd be ok because the integration tests currently don't run in CI. I don't understand what you mean with them being being "blocked locally"? You should be able to run them from your desktop computer, right? That's not a server-side or datacenter IP. |
|
Hey @TheRealAgentK — got to the bottom of it. Cloudflare checks the full TLS fingerprint on api.humanitix.com, not just headers. aiohttp uses a Python TLS stack which Cloudflare flags, regardless of what User-Agent you send. Switched the test fixture to use curl_cffi with Chrome impersonation — it replicates the full Chrome TLS handshake so Cloudflare lets it through. All 5 integration tests now pass locally:
No changes to the integration code itself, just the test fixture. |
…heck_in, check_out
|
Hey @TheRealAgentK, expanded integration tests to cover all 6 actions (was 2 before). Also switched the fixture from Integration test results, 5 passed, 6 skipped, 0 failed11 tests across all 6 actions. Skips are chained tests that need pre-existing events, the test account has no events so they skip gracefully. Run against an account with actual events and all 11 will pass.
|
TheRealAgentK
left a comment
There was a problem hiding this comment.
Local validation: 32/32 unit pass (95% cov), validate_integration.py clean, check_code.py clean. Couldn't run integration tests without a Humanitix key, but the curl_cffi switch looks correct.
A few items to address before merge:
1. os.chdir(_parent) at module level without restore — tests/test_humanitix_integration.py:25
os.chdir(_parent)
_spec = importlib.util.spec_from_file_location(...)Process-global side effect — leaves cwd inside humanitix/ for any test file collected after this one. Same pattern I flagged on #284. The unit test file at least save-and-restores; the integration file doesn't.
2. tests/conftest.py is a no-op — sys.path.insert(0, os.path.dirname(__file__))
That puts tests/ on sys.path, not the integration root. The actual import wiring is the importlib block inside each test file.
Pattern from #280 (supadata): conftest does the path setup once, test files import normally:
# tests/conftest.py
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))# test_humanitix_unit.py
from humanitix import humanitixThe folder/entry-point name collision (humanitix/humanitix.py) doesn't break this — from humanitix import humanitix inside actions/*.py resolves via the partially-loaded module in sys.modules because humanitix = Integration.load() runs before import actions. This drops both the importlib block and the os.chdir calls.
3. Stale tests/context.py — delete
Pre-SDK-2.0 testbed shim (from humanitix import humanitix, dependencies/ path). With conftest fixed per #2 above, this file is unused. Same cleanup as supadata #280.
4. Output schemas still declare "result" (boolean) as required
"required": ["result"]Inconsistent with the established SDK 2.0 pattern (#280 supadata, #289 google-sheets, #307 coda all dropped "result" and "error" from output schemas). Errors now flow through ActionError, so the boolean is dead weight. Either drop it everywhere (preferred) or be explicit about why it's kept.
5. build_error_result is misleadingly named — helpers.py:58
Returns ActionError, not an ActionResult. Minor: rename to build_action_error or inline at the four call sites.
#1 is the only one that risks breaking other test runs; the rest are cleanup that brings this in line with the other SDK 2.0 PRs.
Summary
context.auth.get("credentials", {}).get("api_key", "")inputs.get(), required params useinputs["param"]response.data/response.statusfromFetchResponseActionError(message=...)on errorsTest Results
Unit Tests — 32/32 passed
32 passed ✅
Integration Tests (live Humanitix API) — 5 passed, 6 skipped, 0 failed
11 tests covering all 6 actions. Skipped tests are chained tests that require pre-existing events in the account — they skip gracefully when the account has no events, not a failure.
The test fixture uses
curl_cffiwith Chrome impersonation to bypass Cloudflare's TLS fingerprint check — plainaiohttpgets blocked with a 403 regardless of IP.test_returns_events_listget_eventstest_has_pagination_fieldsget_eventstest_returns_tags_listget_tagstest_tags_structureget_tagstest_pagination_params_respectedget_tagsTestGetOrders(2 tests)get_ordersTestGetTickets(3 tests)get_ticketsTestCheckInOutcheck_in/check_outValidation
validate_integration.pycheck_code.pyHow to run