Skip to content

Add comprehensive test suite with vitest#66

Open
louisabraham wants to merge 5 commits intodelorenj:mainfrom
louisabraham:tests/comprehensive-test-suite
Open

Add comprehensive test suite with vitest#66
louisabraham wants to merge 5 commits intodelorenj:mainfrom
louisabraham:tests/comprehensive-test-suite

Conversation

@louisabraham
Copy link
Copy Markdown

Summary

  • 121 unit tests covering rate-limiter, validators, and trello-client (with mocked axios)
  • 26 smoke tests against live Trello API (auto-skipped when TRELLO_API_KEY/TRELLO_TOKEN env vars are absent)
  • Adds vitest as the test framework with scripts: npm run test, npm run test:unit, npm run test:smoke
  • Tests cover all existing tools plus the new copy_card, copy_checklist, and add_cards_to_list features

Bug found during testing

Some tools return plain text instead of JSON, inconsistent with the rest of the codebase:

  • set_active_board returns "Successfully set active board to..."
  • delete_comment / delete_label return "success" / "Label deleted successfully"
  • All other tools return JSON.stringify(result)

This is a minor inconsistency (not a breaking issue), noted for future cleanup.

Test plan

  • All 121 unit tests pass
  • All 26 smoke tests pass against live Trello board
  • Smoke tests auto-skip when no credentials are set
  • Verify CI integration (add env vars as secrets)

🤖 Generated with Claude Code

louisabraham and others added 2 commits February 11, 2026 02:00
- copy_card: duplicate a card to any list (cross-board) via Trello's
  idCardSource API, with configurable keepFromSource properties
- copy_checklist: copy a checklist with all items to another card
  (cross-board) via idChecklistSource API
- add_cards_to_list: create multiple cards in a single tool call
  with sequential API requests and automatic rate limiting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 121 unit tests covering rate-limiter, validators, and trello-client
- 26 smoke tests against live Trello API (skipped when no credentials)
- Add vitest as test framework with test scripts in package.json
- Tests cover all existing tools plus new copy_card, copy_checklist,
  and add_cards_to_list features

Bug found during testing: some tools (set_active_board, delete_comment,
delete_label) return plain text instead of JSON, inconsistent with
other tools that return JSON objects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 11, 2026 01:10
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @louisabraham, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the project's robustness and functionality by introducing a comprehensive testing framework and new Trello interaction capabilities. The addition of unit and smoke tests ensures greater reliability across core components and new features, while the new tools expand the range of automated Trello operations available. This change improves overall code quality and provides a more stable foundation for future development.

Highlights

  • Comprehensive Test Suite Added: Integrated Vitest as the primary test framework, introducing 121 unit tests covering rate-limiter, validators, and trello-client (with mocked axios), and 26 smoke tests for live Trello API interactions.
  • New Trello Tools Implemented: Added three new tools: copy_card for duplicating Trello cards (including cross-board copies), copy_checklist for copying checklists between cards, and add_cards_to_list for batch creation of multiple cards.
  • Automated Smoke Testing: Smoke tests are configured to automatically skip execution if TRELLO_API_KEY or TRELLO_TOKEN environment variables are not present, ensuring flexibility in test environments.
  • Identified API Inconsistency: Discovered a minor inconsistency where some Trello tools return plain text instead of JSON, unlike the rest of the codebase, which has been noted for future refactoring.
Changelog
  • package-lock.json
    • Updated package version to 1.7.1
    • Added new development dependencies related to Vitest, including various Rollup and Vitest-specific packages, @types/chai, assertion-error, chai, es-module-lexer, estree-walker, expect-type, magic-string, obug, pathe, picocolors, postcss, rollup, siginfo, source-map-js, stackback, std-env, tinybench, tinyexec, tinyglobby, tinyrainbow, vite, and why-is-node-running.
  • package.json
    • Updated package version to 1.7.1
    • Added vitest as a development dependency
    • Introduced new npm scripts for testing: test (runs all tests), test:unit (runs unit tests), test:smoke (runs smoke tests), and test:watch (runs Vitest in watch mode).
  • src/index.ts
    • Registered a new tool copy_card to duplicate Trello cards with various options like name, description, and properties to keep from the source.
    • Registered a new tool copy_checklist to copy checklists from one card to another, allowing custom naming and positioning.
    • Registered a new tool add_cards_to_list to facilitate adding multiple cards to a Trello list in a single operation, handling sequential creation and rate limiting.
  • src/trello-client.ts
    • Implemented copyCard method to handle Trello card duplication, supporting cross-board copies and selective property retention.
    • Implemented copyChecklist method to copy checklists between Trello cards.
    • Implemented batchAddCards method to sequentially add multiple cards to a specified list, managing Trello API's lack of native batch write functionality.
  • tests/smoke/smoke.test.ts
    • Added a new file containing 26 smoke tests designed to interact with the live Trello API.
    • Included a McpTestClient helper class to simulate communication with the MCP server for testing purposes.
    • Implemented beforeAll and afterAll hooks for setting up a test list and cleaning up created cards by archiving them.
  • tests/unit/rate-limiter.test.ts
    • Added a new file containing unit tests for TokenBucketRateLimiter to verify token consumption, refilling, and rate adherence.
    • Included tests for createTrelloRateLimiters to ensure correct Trello API rate limits are applied and respected.
  • tests/unit/trello-client.test.ts
    • Added a new file containing comprehensive unit tests for the TrelloClient class.
    • Utilized vi.mock to mock axios and rate-limiter dependencies, isolating TrelloClient logic for testing.
    • Covered various TrelloClient methods including board, card, list, comment, checklist, member, and label operations, as well as the newly added copyCard, copyChecklist, and batchAddCards.
  • tests/unit/validators.test.ts
    • Added a new file containing unit tests for various input validation functions.
    • Tested primitive validators for strings, numbers, booleans, arrays, and date formats.
    • Included tests for request-specific validators to ensure correct input schemas for Trello API calls.
  • vitest.config.ts
    • Added a new file to configure Vitest, specifying global test variables, test file inclusion patterns, and a default test timeout.
Activity
  • The author, louisabraham, initiated this pull request to add a comprehensive test suite using Vitest.
  • 121 unit tests have been successfully implemented and are passing, covering core functionalities.
  • 26 smoke tests have been developed and are passing against a live Trello board, validating real API interactions.
  • The smoke tests are designed to automatically skip if Trello API credentials are not provided in the environment.
  • A minor inconsistency in API tool return types (plain text vs. JSON) was noted during the testing process for future consideration.
  • Verification of CI integration for environment variables as secrets is a pending task.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive test suite using vitest, which is a great addition for ensuring code quality and stability. The new features for copying cards/checklists and batch-adding cards are also well-implemented. The tests are thorough, covering unit tests with mocks and smoke tests against the live API. I've identified a few areas for improvement, mainly around making the code more robust and efficient.

src/index.ts Outdated
Comment on lines +1275 to +1294
cards: z
.array(
z.object({
name: z.string().describe('Name of the card'),
description: z.string().optional().describe('Description of the card'),
dueDate: z
.string()
.optional()
.describe('Due date for the card (ISO 8601 format)'),
start: z
.string()
.optional()
.describe('Start date for the card (YYYY-MM-DD format)'),
labels: z
.array(z.string())
.optional()
.describe('Array of label IDs to apply to the card'),
})
)
.describe('Array of cards to create'),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The cards array in the add_cards_to_list tool's input schema can be empty. While not a critical issue, allowing an empty array could lead to a successful tool call that performs no action, which might be confusing for the user. It's better to enforce that at least one card is provided.

          cards: z
            .array(
              z.object({
                name: z.string().describe('Name of the card'),
                description: z.string().optional().describe('Description of the card'),
                dueDate: z
                  .string()
                  .optional()
                  .describe('Due date for the card (ISO 8601 format)'),
                start: z
                  .string()
                  .optional()
                  .describe('Start date for the card (YYYY-MM-DD format)'),
                labels: z
                  .array(z.string())
                  .optional()
                  .describe('Array of label IDs to apply to the card'),
              })
            )
            .min(1, { message: 'Must provide at least one card to create.' })
            .describe('Array of cards to create'),

Comment on lines +1130 to +1142
for (const card of cards) {
const result = await this.addCard(undefined, {
listId,
name: card.name,
description: card.description,
dueDate: card.dueDate,
start: card.start,
labels: card.labels,
});
results.push(result);
}
return results;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation of batchAddCards uses a sequential for...of loop with await, which adds cards one by one. This can be inefficient for a large number of cards. You can improve performance by executing the card creation requests in parallel using Promise.all. The existing rate limiter will automatically handle the concurrent requests and queue them as needed.

Suggested change
for (const card of cards) {
const result = await this.addCard(undefined, {
listId,
name: card.name,
description: card.description,
dueDate: card.dueDate,
start: card.start,
labels: card.labels,
});
results.push(result);
}
return results;
}
const cardPromises = cards.map(card =>
this.addCard(undefined, {
listId,
name: card.name,
description: card.description,
dueDate: card.dueDate,
start: card.start,
labels: card.labels,
})
);
return Promise.all(cardPromises);

Comment on lines +7 to +9
const TEST_BOARD_ID = process.env.TRELLO_TEST_BOARD_ID || '698bd319de70fa4f7a3c7ccd';

const canRunSmoke = Boolean(TRELLO_API_KEY && TRELLO_TOKEN);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The smoke tests include a hardcoded fallback for TEST_BOARD_ID. This is not ideal as it can lead to flaky tests or unintended side effects if multiple developers run tests against the same shared board. It's better to rely exclusively on environment variables for configuration and skip the tests if they are not provided. This makes the tests more portable and safer to run in a collaborative environment.

Suggested change
const TEST_BOARD_ID = process.env.TRELLO_TEST_BOARD_ID || '698bd319de70fa4f7a3c7ccd';
const canRunSmoke = Boolean(TRELLO_API_KEY && TRELLO_TOKEN);
const TEST_BOARD_ID = process.env.TRELLO_TEST_BOARD_ID;
const canRunSmoke = Boolean(TRELLO_API_KEY && TRELLO_TOKEN && TEST_BOARD_ID);

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a Vitest-based test suite for the Trello MCP server, adding broad unit coverage for core modules plus optional live “smoke” tests against the Trello API. It also adds three new user-facing tools (copy_card, copy_checklist, add_cards_to_list) with corresponding client methods.

Changes:

  • Add Vitest configuration and npm scripts for unit and smoke test runs
  • Add unit tests for validators, rate-limiter, and trello-client (with mocked axios/fs)
  • Add new Trello features/tools: copy card, copy checklist, and batch-add cards to a list (plus live smoke tests)

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vitest.config.ts Adds Vitest runner configuration (globals, include pattern, timeout).
tests/unit/validators.test.ts Unit tests for primitive + request validator helpers.
tests/unit/trello-client.test.ts Unit tests for TrelloClient behaviors using mocked axios/rate-limiter/fs.
tests/unit/rate-limiter.test.ts Unit tests for token-bucket limiter timing/consumption behavior.
tests/smoke/smoke.test.ts Live Trello API smoke tests via spawning the built MCP server and calling tools over stdio JSON-RPC.
src/trello-client.ts Adds copyCard, copyChecklist, and batchAddCards methods.
src/index.ts Registers new MCP tools: copy_card, copy_checklist, add_cards_to_list.
package.json Adds vitest devDependency and test:* scripts.
package-lock.json Lockfile updates for Vitest/Vite dependency tree.

@@ -0,0 +1,448 @@
import { describe, it, expect, beforeAll } from 'vitest';
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

afterAll is used later in this file but isn’t imported from vitest, which will cause the smoke test suite to fail to compile/run. Add afterAll to the import list (or remove the hook).

Suggested change
import { describe, it, expect, beforeAll } from 'vitest';
import { describe, it, expect, beforeAll, afterAll } from 'vitest';

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +9
const TEST_BOARD_ID = process.env.TRELLO_TEST_BOARD_ID || '698bd319de70fa4f7a3c7ccd';

const canRunSmoke = Boolean(TRELLO_API_KEY && TRELLO_TOKEN);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The smoke tests default TEST_BOARD_ID to a hard-coded board ID. If someone runs smoke tests with credentials but forgets to set TRELLO_TEST_BOARD_ID, these tests will create/archive data on an arbitrary board. Consider requiring TRELLO_TEST_BOARD_ID to be set (and skip otherwise), or default to a clearly local/test board created during setup.

Copilot uses AI. Check for mistakes.
Comment on lines 41 to 45
"prettier": "^3.7.4",
"terser": "^5.44.1",
"typescript": "^5.9.3"
"typescript": "^5.9.3",
"vitest": "^4.0.18"
},
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

Adding vitest@^4.0.18 implicitly raises the minimum Node.js version required to run tests/install devDependencies (per the lockfile, Vitest requires Node ^20.0.0 || ^22.0.0 || >=24.0.0, and it pulls in Vite with a Node 20+ engine). If this repo is meant to keep npx/Node workflows working on older Node versions, consider either (a) pinning to a Vitest/Vite version compatible with the supported Node range, or (b) explicitly documenting/enforcing the required Node version via engines.node and CI.

Copilot uses AI. Check for mistakes.
Comment on lines +1129 to +1141
const results: TrelloCard[] = [];
for (const card of cards) {
const result = await this.addCard(undefined, {
listId,
name: card.name,
description: card.description,
dueDate: card.dueDate,
start: card.start,
labels: card.labels,
});
results.push(result);
}
return results;
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

batchAddCards is non-atomic: if a later addCard call fails, earlier cards have already been created but the error aborts without returning which cards succeeded. To make this safer for users/ops, consider returning partial results + per-card errors, or adding an option like continueOnError / rollbackOnFailure (best-effort archive) so callers can avoid leaving orphaned cards.

Copilot uses AI. Check for mistakes.
Comment on lines +1174 to +1181
// Copy a card (supports cross-board copy)
this.server.registerTool(
'copy_card',
{
title: 'Copy Card',
description:
'Copy/duplicate a Trello card to any list (even on a different board). Copies all properties by default including checklists, attachments, comments, labels, etc.',
inputSchema: {
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

New user-facing tools (copy_card, copy_checklist, add_cards_to_list) are added here, but the README’s “Available Tools” section appears to be the canonical tool documentation and currently doesn’t mention them. Please update README.md to document these tools (arguments + return shape) so users can discover and use them.

Copilot uses AI. Check for mistakes.
@louisabraham
Copy link
Copy Markdown
Author

Thanks for the reviews! Addressed the feedback in https://github.com/louisabraham/mcp-server-trello/tree/anthony:

Fixed:

  • Added missing afterAll import in smoke tests (real bug, good catch!)
  • Removed hardcoded TEST_BOARD_ID — now requires TRELLO_TEST_BOARD_ID env var (tests skip if absent)
  • cards array enforces .min(1) validation
  • Updated test assertions for the new batchAddCards return shape {created, errors}
  • Added test for partial failure handling and card limit enforcement

Note on Node version: vitest@4 does require Node 20+, which is reasonable for a dev dependency. The runtime itself (bun) has its own requirements.

louisabraham and others added 3 commits February 11, 2026 03:13
Return {created, errors} so callers see which cards succeeded even
if some fail. Enforce a 50-card maximum to prevent long-running calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tests

- Import afterAll from vitest (was used but not imported)
- Require TRELLO_TEST_BOARD_ID env var instead of hardcoding
- Update test assertions for new batchAddCards {created, errors} return
- Add tests for partial failure handling and card limit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Uses dotenv to load TRELLO_API_KEY, TRELLO_TOKEN, and
TRELLO_TEST_BOARD_ID from .env so smoke tests can run
with just `npm run test:smoke` (no manual env vars needed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@louisabraham
Copy link
Copy Markdown
Author

Update: Added .env file loading to vitest config so smoke tests can run with just npm run test:smoke — no need to manually pass env vars.

Setup: Create a .env file at the project root:

TRELLO_API_KEY=your-key
TRELLO_TOKEN=your-token
TRELLO_TEST_BOARD_ID=your-test-board-id

Then run:

npm run test        # all tests (unit + smoke)
npm run test:unit   # unit tests only (no credentials needed)
npm run test:smoke  # smoke tests only (requires .env)

The .env file is already gitignored.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants