Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions tests/fixtures/api_contracts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# API contract test fixtures

Recorded JSON payloads used by `tests/test_api_contracts.py` to verify that
GitHub and Slack API responses still deserialize through the Pydantic boundary
schemas in `github_activity_tracker.api_schemas` and `cppa_slack_tracker.api_schemas`.

## Filename convention

`<provider>_<resource>_<YYYY-MM-DD>.json`

The date suffix is the **recording date** (when the fixture was captured or last
refreshed), not the API event timestamp inside the JSON.

## When to refresh

- After GitHub or Slack API version or field changes that affect collectors
- After changing boundary parsers or Pydantic models in `api_schemas.py`
- When contract tests fail in CI with validation errors on these fixtures

## How to refresh

1. Capture a representative response from the live API (or from fetcher/sync debug output).
2. Redact secrets and sensitive data (see below).
3. Save under this directory with a **new** recording date in the filename.
4. Remove or keep older dated files; contract tests glob all matching prefixes.
5. Run: `uv run pytest tests/test_api_contracts.py -v`

### Example: GitHub issue (nested bundle shape)

```bash
# Replace TOKEN, owner, repo, and issue number.
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/OWNER/REPO/issues/NUMBER" \
> /tmp/issue.json
# Wrap as fetcher bundle if needed: {"issue_info": <issue>, "comments": [...]}
```

### Example: Slack channel (`conversations.list` member)

Use a public channel object from Slack Web API responses; ensure `is_channel: true`
and `is_private: false` if testing channel ingestion paths.

## Redaction rules

- Do **not** commit API tokens, bot tokens, or webhook URLs.
- Mask or omit real user emails when possible (`@example.com` placeholders are fine).
- Trim large binary or irrelevant fields; keep fields the collector parsers use.

## Fixture inventory

| File | Parser |
|------|--------|
| `github_issue_bundle_*.json` | `parse_issue_bundle` |
| `github_pr_bundle_*.json` | `parse_pr_bundle` |
| `github_commit_*.json` | `parse_commit` |
| `slack_team_*.json` | `parse_team` |
| `slack_channel_*.json` | `parse_channel` |
| `slack_user_*.json` | `parse_user` |
| `slack_message_*.json` | `parse_message` |
46 changes: 46 additions & 0 deletions tests/fixtures/api_contracts/github_commit_2026-05-28.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"sha": "a1b2c3d4e5f6789012345678901234567890abcd",
"author": {
"id": 583231,
"login": "octocat",
"name": "The Octocat",
"avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
},
"committer": {
"id": 583231,
"login": "octocat"
},
"commit": {
"message": "Contract test commit message\n\nMulti-line body.",
"author": {
"name": "The Octocat",
"email": "octocat@users.noreply.github.com",
"date": "2024-03-10T12:00:00Z"
},
"committer": {
"name": "The Octocat",
"email": "octocat@users.noreply.github.com",
"date": "2024-03-10T12:00:00Z"
}
},
"files": [
{
"filename": "src/main.cpp",
"status": "modified",
"additions": 12,
"deletions": 3,
"patch": "@@ -1,3 +1,12 @@\n+// example"
},
{
"filename": "README.md",
"status": "added",
"additions": 5,
"deletions": 0
}
],
"stats": {
"additions": 17,
"deletions": 3,
"total": 20
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"issue_info": {
"number": 42,
"id": 2847291001,
"title": "Contract test issue",
"body": "Body from recorded GitHub-style payload.",
"state": "open",
"state_reason": "reopened",
"user": {
"id": 583231,
"login": "octocat",
"name": "The Octocat",
"avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
},
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-20T14:30:00Z",
"closed_at": null,
"assignees": [
{
"id": 991001,
"login": "assignee-one",
"name": "Assignee One"
}
],
"labels": [
{"name": "bug"},
{"name": "help wanted"}
]
},
"comments": [
{
"id": 9001001,
"body": "First comment on issue.",
"user": {
"id": 583231,
"login": "octocat",
"name": "The Octocat"
},
"created_at": "2024-01-16T09:00:00Z",
"updated_at": "2024-01-16T09:00:00Z"
}
]
}
41 changes: 41 additions & 0 deletions tests/fixtures/api_contracts/github_pr_bundle_2026-05-28.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"pr_info": {
"number": 17,
"id": 3847291002,
"title": "Contract test pull request",
"body": "PR body from recorded GitHub-style payload.",
"state": "open",
"user": {
"id": 583231,
"login": "octocat",
"name": "The Octocat",
"avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
},
"head": {"sha": "feature-branch-sha-abc123def456"},
"base": {"sha": "main-branch-sha-789012345678"},
"created_at": "2024-02-01T08:00:00Z",
"updated_at": "2024-02-05T16:45:00Z",
"merged_at": null,
"assignees": [],
"labels": [{"name": "enhancement"}]
},
"comments": [
{
"id": 9002001,
"body": "PR discussion comment.",
"user": {"id": 583231, "login": "octocat"},
"created_at": "2024-02-02T11:00:00Z",
"updated_at": "2024-02-02T11:00:00Z"
}
],
"reviews": [
{
"id": 8003001,
"body": "Looks good.",
"user": {"id": 991002, "login": "reviewer-one"},
"in_reply_to_id": null,
"created_at": "2024-02-03T10:00:00Z",
"updated_at": "2024-02-03T10:00:00Z"
}
]
}
23 changes: 23 additions & 0 deletions tests/fixtures/api_contracts/slack_channel_2026-05-28.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"id": "C0CONTRACT01",
"name": "general",
"is_channel": true,
"is_private": false,
"is_im": false,
"is_mpim": false,
"is_archived": false,
"is_general": true,
"creator": "U0CONTRACT01",
"created": 1609459200,
"purpose": {
"value": "Company-wide announcements and work-based matters",
"creator": "U0CONTRACT01",
"last_set": 1609459200
},
"topic": {
"value": "General discussion",
"creator": "U0CONTRACT01",
"last_set": 1609459200
},
"num_members": 42
}
19 changes: 19 additions & 0 deletions tests/fixtures/api_contracts/slack_message_2026-05-28.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"type": "message",
"subtype": null,
"user": "U0CONTRACT01",
"text": "Contract test message from recorded Slack-style payload.",
"ts": "1710000000.123456",
"thread_ts": null,
"edited": {
"user": "U0CONTRACT01",
"ts": "1710000100.654321"
},
"reactions": [
{
"name": "thumbsup",
"count": 2,
"users": ["U0CONTRACT01", "U0CONTRACT02"]
}
]
}
11 changes: 11 additions & 0 deletions tests/fixtures/api_contracts/slack_team_2026-05-28.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": "T0CONTRACT01",
"name": "Contract Test Workspace",
"domain": "contract-test",
"email_domain": "example.com",
"icon": {
"image_68": "https://example.com/team-icon-68.png"
},
"enterprise_id": null,
"enterprise_name": null
}
17 changes: 17 additions & 0 deletions tests/fixtures/api_contracts/slack_user_2026-05-28.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"id": "U0CONTRACT01",
"name": "contract.user",
"real_name": "Contract Test User",
"deleted": false,
"is_bot": false,
"is_app_user": false,
"updated": 1710000000,
"profile": {
"email": "contract.user@example.com",
"image_72": "https://example.com/avatar-72.png",
"display_name": "contractuser",
"real_name": "Contract Test User",
"title": "Engineer"
},
"team_id": "T0CONTRACT01"
}
Loading
Loading