-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add integration tests for /campaigns/** endpoints
#2975
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds a new end-to-end test exercising campaign lifecycle (create, update, publish, pause, resume, duplicate, list, retrieve, delete) and a helper method on the test IntegrationHarness to delete campaigns. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Test as E2E Test (IntegrationHarness)
participant API as Campaign API
participant DB as Database
rect rgb(240,248,255)
Test->>API: POST /campaigns (create draft)
API->>DB: Insert draft campaign
DB-->>API: Campaign record (id)
API-->>Test: 201 Created (campaignId)
end
rect rgb(245,245,220)
Test->>API: PATCH /campaigns/{id} (update content/groups)
API->>DB: Update campaign fields
DB-->>API: Updated campaign
API-->>Test: 200 OK (draft campaign)
end
rect rgb(240,255,240)
Test->>API: PATCH /campaigns/{id} (status: active)
API->>DB: Set status=active
DB-->>API: Active campaign
API-->>Test: 200 OK (active)
end
rect rgb(255,240,245)
Test->>API: PATCH /campaigns/{id} (status: paused)
API->>DB: Set status=paused
DB-->>API: Paused campaign
API-->>Test: 200 OK (paused)
end
rect rgb(240,255,240)
Test->>API: PATCH /campaigns/{id} (status: active)
API->>DB: Set status=active
DB-->>API: Active campaign
API-->>Test: 200 OK (active)
end
rect rgb(250,250,210)
Test->>API: POST /campaigns/{id}/duplicate
API->>DB: Copy campaign record (new id, name " (copy)", draft)
DB-->>API: Duplicate campaign record
API-->>Test: 201 Created (duplicateId)
end
rect rgb(250,250,250)
Test->>API: GET /campaigns (list)
API->>DB: Query campaigns
DB-->>API: Campaign list
API-->>Test: 200 OK (array includes created campaign)
Test->>API: GET /campaigns/{id}
API->>DB: Fetch campaign by id
DB-->>API: Campaign
API-->>Test: 200 OK (campaign details)
Test->>API: DELETE /campaigns/{id}
API->>DB: Delete campaign
DB-->>API: Deleted id
API-->>Test: 200 OK (deleted campaignId)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
apps/web/tests/campaigns/index.test.ts (3)
40-44: Consider adding cleanup for failed test runs.The sequential test design appropriately models the campaign lifecycle, but there's no cleanup mechanism if tests fail before the DELETE operation. Consider adding an
afterAllhook or similar cleanup to remove test campaigns, preventing pollution of the test database.Example:
afterAll(async () => { if (campaignId) { try { await http.delete({ path: `/campaigns/${campaignId}` }); } catch { // Campaign already deleted or doesn't exist } } });
79-125: LGTM!The status transition tests properly validate the campaign lifecycle (publish, pause, resume) and confirm that other fields remain unchanged during status updates.
Optional: Consider adding tests for invalid status transitions (e.g., direct draft→paused without publishing first) to ensure the API properly validates state machine rules.
153-175: LGTM!The GET and DELETE operations are correctly tested and validated.
Optional: Consider adding a verification step after deletion to confirm the campaign no longer exists (e.g., GET should return 404):
test("DELETE /campaigns/[campaignId] - delete campaign", async () => { const { status, data } = await http.delete<{ id: string }>({ path: `/campaigns/${campaignId}`, }); expect(status).toEqual(200); expect(data).toStrictEqual({ id: campaignId, }); // Verify deletion const { status: getStatus } = await http.get({ path: `/campaigns/${campaignId}`, }); expect(getStatus).toEqual(404); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/tests/campaigns/index.test.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/tests/campaigns/index.test.ts (3)
apps/web/lib/zod/schemas/campaigns.ts (1)
updateCampaignSchema(80-96)apps/web/lib/types.ts (2)
Campaign(660-660)CampaignList(658-658)apps/web/tests/utils/resource.ts (1)
E2E_PARTNER_GROUP(102-105)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (6)
apps/web/tests/campaigns/index.test.ts (6)
1-6: LGTM!The imports are clean, well-organized, and include all necessary dependencies for the test suite.
8-30: LGTM!The campaign test data is well-structured and appropriately typed. Omitting
groupIdsandstatushere allows individual tests to control these fields explicitly.
32-38: LGTM!The expected campaign structure properly uses
expect.any(String)for timestamp validation and correctly transforms the group ID into the expected response shape.
46-60: LGTM!The campaign creation test correctly validates the minimal payload approach and captures the campaign ID for subsequent tests.
62-77: LGTM!The update test properly validates that campaign content can be modified while maintaining draft status. The assertion correctly verifies all expected fields.
127-151: LGTM!The list campaigns test correctly validates the response structure, including the metrics fields specific to the
CampaignListtype. The assertion appropriately uses a different structure thanexpectedCampaignbecause the list endpoint returns additional metric fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
apps/web/tests/campaigns/index.test.ts (2)
79-138: LGTM! Status transitions are well-tested.The test flow correctly verifies the campaign status lifecycle (draft → active → paused → active).
Consider adding negative test cases for invalid status transitions (e.g., draft → paused) to ensure the API properly validates state transitions.
40-213: Consider adding error case tests.The test suite comprehensively covers happy paths but could benefit from error case testing to ensure the API properly handles invalid inputs and states. Consider adding tests for:
- Invalid campaign IDs (404 responses)
- Invalid status transitions
- Missing required fields on create/update
- Invalid groupIds
- Attempting to delete a non-existent campaign
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/web/tests/campaigns/index.test.ts(1 hunks)apps/web/tests/utils/integration.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/tests/campaigns/index.test.ts (4)
apps/web/lib/zod/schemas/campaigns.ts (1)
updateCampaignSchema(80-96)apps/web/lib/types.ts (2)
Campaign(660-660)CampaignList(658-658)apps/web/tests/utils/resource.ts (1)
E2E_PARTNER_GROUP(102-105)apps/web/tests/utils/integration.ts (1)
IntegrationHarness(14-118)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (7)
apps/web/tests/utils/integration.ts (1)
110-117: LGTM! Consistent with existing delete methods.The implementation follows the established pattern for resource cleanup methods in the harness (early return for falsy IDs, simple DELETE request).
apps/web/tests/campaigns/index.test.ts (6)
1-38: LGTM! Clean test setup.The test data structure and expected baseline are well-defined, providing clear fixtures for the lifecycle tests.
46-60: LGTM!Creates a minimal draft campaign and captures the ID for subsequent tests.
62-77: LGTM!The test correctly updates the draft campaign with full content and verifies the response structure, including the transformation from
groupIdsinput togroupsoutput.
140-162: LGTM! Duplication properly tested with cleanup.The test correctly duplicates the campaign, registers cleanup for the duplicate, and verifies the expected name suffix and draft status.
190-201: LGTM!Final verification that the campaign is still in the expected active state before deletion.
164-188: Remove this review comment—the API response types are intentionally differentiated.The schemas are correctly designed:
CampaignListSchemaincludes metrics (delivered,sent,bounced,opened) for list responses, whileCampaignSchemaexcludes metrics and includes detailed fields (subject,bodyJson,triggerCondition) for single-resource responses. This is intentional, not an inconsistency. The test uses the correct types for their respective endpoints.Likely an incorrect or invalid review comment.
Summary by CodeRabbit