Skip to content

fix(humanitix): upgrade SDK to v2.0.0, add unit and integration tests (#304)#306

Open
Shubhank-Jonnada wants to merge 6 commits intomasterfrom
fix/304/humanitix-sdk-v2
Open

fix(humanitix): upgrade SDK to v2.0.0, add unit and integration tests (#304)#306
Shubhank-Jonnada wants to merge 6 commits intomasterfrom
fix/304/humanitix-sdk-v2

Conversation

@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor

@Shubhank-Jonnada Shubhank-Jonnada commented Apr 30, 2026

Summary

  • Upgrades Humanitix integration to SDK 2.0.0
  • Fixes auth pattern: context.auth.get("credentials", {}).get("api_key", "")
  • Fixes error handling with non-dict response bodies (Cloudflare HTML responses)
  • All optional params use inputs.get(), required params use inputs["param"]
  • Uses response.data / response.status from FetchResponse
  • Returns ActionError(message=...) on errors
  • Bumped version to 2.0.0
  • Added integration tests covering all 6 actions

Test 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_cffi with Chrome impersonation to bypass Cloudflare's TLS fingerprint check — plain aiohttp gets blocked with a 403 regardless of IP.

Test Action Status
test_returns_events_list get_events ✅ PASSED
test_has_pagination_fields get_events ✅ PASSED
test_returns_tags_list get_tags ✅ PASSED
test_tags_structure get_tags ✅ PASSED
test_pagination_params_respected get_tags ✅ PASSED
TestGetOrders (2 tests) get_orders ⏭ SKIPPED (no events in account)
TestGetTickets (3 tests) get_tickets ⏭ SKIPPED (no events in account)
TestCheckInOut check_in / check_out ⏭ SKIPPED (no events in account)
Validation
Check Result
validate_integration.py ✅ PASSED (0 errors, 0 warnings)
check_code.py ✅ PASSED

How to run

# Unit tests
python -m pytest humanitix/tests/test_humanitix_unit.py -m unit -v

# Integration tests (requires API key)
HUMANITIX_API_KEY=<your-key> python -m pytest humanitix/tests/test_humanitix_integration.py -m integration -v

# Destructive tests only (check_in / check_out)
HUMANITIX_API_KEY=<your-key> python -m pytest humanitix/tests/test_humanitix_integration.py -m "integration and destructive" -v

…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
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

🔍 Integration Validation Results

Commit: 2c4a427400e8c64796bb45eef347eb78ceddd91e · test(humanitix): add integration tests for get_orders, get_tickets, check_in, check_out
Updated: 2026-05-04T04:08:50Z

Changed directories: humanitix

Check Result
Structure ✅ Passed
Code ✅ Passed
Tests ✅ Passed
README ✅ Passed
Version ✅ Passed
✅ Structure Check output
Validating 1 integration(s)...

============================================================
Integration: humanitix
============================================================
✅ All checks passed!

============================================================
SUMMARY
============================================================
Integrations validated: 1
Total errors: 0
Total warnings: 0

✅ All validations passed!
✅ Code Check output

[notice] A new release of pip is available: 26.0.1 -> 26.1
[notice] To update, run: pip install --upgrade pip
----------------------------------------
Checking: humanitix
----------------------------------------

📦 Installing dependencies...

🐍 Checking Python syntax...
   ✅ Syntax OK

📥 Checking imports...
   ✅ Imports OK

📄 Checking JSON files...
   ✅ JSON files OK

🔍 Linting with ruff...
   ✅ Lint OK

🎨 Checking formatting with ruff...
   ✅ Formatting OK

🔒 Scanning for security issues with bandit...
   ✅ Security OK

🛡️ Checking dependencies for vulnerabilities with pip-audit...
   ✅ Dependencies OK

🔗 Checking config-code sync...
   ✅ Config-code sync OK

🔄 Checking fetch patterns...
   ✅ Fetch patterns OK

========================================
✅ CODE CHECK PASSED
========================================
✅ Tests Check output

Integration   Tests  Coverage        Status
-------------------------------------------
humanitix     32/32       95%      ✅ Passed
-------------------------------------------
Total         32/32            ✅ All passed

✅ Tests passed: humanitix
✅ README Check output
========================================
✅ README CHECK PASSED
========================================
✅ Version Check output
✅ humanitix: 1.0.0 → 2.0.0 (major bump)

========================================
✅ VERSION CHECK PASSED
========================================

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread humanitix/helpers.py Outdated
@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor Author

@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.

@TheRealAgentK
Copy link
Copy Markdown
Collaborator

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.

@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor Author

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:

  • test_returns_events_list PASSED
  • test_has_pagination_fields PASSED
  • test_returns_tags_list PASSED
  • test_tags_structure PASSED
  • test_pagination_params_respected PASSED

No changes to the integration code itself, just the test fixture.

@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor Author

Shubhank-Jonnada commented May 4, 2026

Hey @TheRealAgentK, expanded integration tests to cover all 6 actions (was 2 before). Also switched the fixture from aiohttp to curl_cffi with Chrome impersonation to bypass Cloudflare's TLS fingerprint check.

Integration test results, 5 passed, 6 skipped, 0 failed

11 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.

Test Action Status
test_returns_events_list get_events ✅ PASSED
test_has_pagination_fields get_events ✅ PASSED
test_returns_tags_list get_tags ✅ PASSED
test_tags_structure get_tags ✅ PASSED
test_pagination_params_respected get_tags ✅ PASSED
TestGetOrders (2 tests) get_orders ⏭ SKIPPED (no events in account)
TestGetTickets (3 tests) get_tickets ⏭ SKIPPED (no events in account)
TestCheckInOut check_in / check_out ⏭ SKIPPED (no events in account)

Copy link
Copy Markdown
Collaborator

@TheRealAgentK TheRealAgentK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 humanitix

The 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants