Add missing OAuth scopes and improve documentation
Changes: - Add script.processes and drive.readonly scopes to SCRIPT_SCOPES (required for list_script_processes and list_script_projects) - Update README.md with detailed Google Cloud setup instructions - Add run_script_function API Executable deployment documentation - Create TESTING.md with unit test and E2E testing guides - Update manual_test.py to use configurable credential paths - Add headless Linux authentication flow documentation
This commit is contained in:
254
gappsscript/TESTING.md
Normal file
254
gappsscript/TESTING.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# Apps Script MCP Testing Guide
|
||||
|
||||
This document provides instructions for running unit tests and end-to-end (E2E) tests for the Apps Script MCP feature.
|
||||
|
||||
## Test Structure
|
||||
|
||||
```
|
||||
tests/gappsscript/
|
||||
__init__.py
|
||||
test_apps_script_tools.py # Unit tests with mocked API
|
||||
manual_test.py # E2E tests against real API
|
||||
```
|
||||
|
||||
## Unit Tests
|
||||
|
||||
Unit tests use mocked API responses and do not require Google credentials.
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
```bash
|
||||
# Run all Apps Script unit tests
|
||||
uv run pytest tests/gappsscript/test_apps_script_tools.py -v
|
||||
|
||||
# Run specific test
|
||||
uv run pytest tests/gappsscript/test_apps_script_tools.py::test_list_script_projects -v
|
||||
|
||||
# Run with coverage
|
||||
uv run pytest tests/gappsscript/test_apps_script_tools.py --cov=gappsscript
|
||||
```
|
||||
|
||||
### Test Coverage
|
||||
|
||||
Unit tests cover:
|
||||
- list_script_projects (uses Drive API)
|
||||
- get_script_project
|
||||
- get_script_content
|
||||
- create_script_project
|
||||
- update_script_content
|
||||
- run_script_function
|
||||
- create_deployment
|
||||
- list_deployments
|
||||
- update_deployment
|
||||
- delete_deployment
|
||||
- list_script_processes
|
||||
|
||||
## E2E Tests
|
||||
|
||||
E2E tests interact with the real Google Apps Script API. They require valid OAuth credentials and will create real resources in your Google account.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **Google Cloud Project** with Apps Script API and Drive API enabled
|
||||
2. **OAuth credentials** (Desktop application type)
|
||||
3. **Test user** added to OAuth consent screen
|
||||
|
||||
### Setup
|
||||
|
||||
**Option 1: Default paths (recommended for CI)**
|
||||
|
||||
Place credentials in the project root:
|
||||
```bash
|
||||
# Place your OAuth client credentials here
|
||||
cp /path/to/your/client_secret.json ./client_secret.json
|
||||
```
|
||||
|
||||
**Option 2: Custom paths via environment variables**
|
||||
|
||||
```bash
|
||||
export GOOGLE_CLIENT_SECRET_PATH=/path/to/client_secret.json
|
||||
export GOOGLE_TOKEN_PATH=/path/to/token.pickle
|
||||
```
|
||||
|
||||
### Running E2E Tests
|
||||
|
||||
```bash
|
||||
# Interactive mode (prompts for confirmation)
|
||||
uv run python tests/gappsscript/manual_test.py
|
||||
|
||||
# Non-interactive mode (for CI)
|
||||
uv run python tests/gappsscript/manual_test.py --yes
|
||||
```
|
||||
|
||||
### E2E Test Flow
|
||||
|
||||
The test script performs the following operations:
|
||||
|
||||
1. **List Projects** - Lists existing Apps Script projects via Drive API
|
||||
2. **Create Project** - Creates a new test project
|
||||
3. **Get Project** - Retrieves project details
|
||||
4. **Update Content** - Adds code to the project
|
||||
5. **Run Function** - Attempts to execute a function (see note below)
|
||||
6. **Create Deployment** - Creates a versioned deployment
|
||||
7. **List Deployments** - Lists all deployments
|
||||
8. **List Processes** - Lists recent script executions
|
||||
|
||||
### Cleanup
|
||||
|
||||
The test script does not automatically delete created projects. After running tests:
|
||||
|
||||
1. Go to [Google Apps Script](https://script.google.com/)
|
||||
2. Find projects named "MCP Test Project"
|
||||
3. Delete them manually via the menu (three dots) > Remove
|
||||
|
||||
## Headless Linux Testing
|
||||
|
||||
For headless environments (servers, CI/CD, WSL without GUI):
|
||||
|
||||
### OAuth Authentication Flow
|
||||
|
||||
The test script uses a headless-compatible OAuth flow:
|
||||
|
||||
1. Script prints an authorization URL
|
||||
2. Open the URL in any browser (can be on a different machine)
|
||||
3. Complete Google sign-in and authorization
|
||||
4. Browser redirects to `http://localhost/?code=...` (page will not load)
|
||||
5. Copy the full URL from the browser address bar
|
||||
6. Paste it into the terminal when prompted
|
||||
|
||||
### Example Session
|
||||
|
||||
```
|
||||
$ python tests/gappsscript/manual_test.py --yes
|
||||
|
||||
============================================================
|
||||
HEADLESS AUTH
|
||||
============================================================
|
||||
|
||||
1. Open this URL in any browser:
|
||||
|
||||
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=...
|
||||
|
||||
2. Sign in and authorize the app
|
||||
3. You'll be redirected to http://localhost (won't load)
|
||||
4. Copy the FULL URL from browser address bar
|
||||
(looks like: http://localhost/?code=4/0A...&scope=...)
|
||||
5. Paste it below:
|
||||
|
||||
Paste full redirect URL: http://localhost/?code=4/0AQSTgQ...&scope=...
|
||||
|
||||
Building API services...
|
||||
|
||||
=== Test: List Projects ===
|
||||
Found 3 Apps Script projects:
|
||||
...
|
||||
```
|
||||
|
||||
### Credential Storage
|
||||
|
||||
OAuth tokens are stored as pickle files:
|
||||
- Default: `./test_token.pickle` in project root
|
||||
- Custom: Set via `GOOGLE_TOKEN_PATH` environment variable
|
||||
|
||||
Tokens are reused on subsequent runs until they expire or are revoked.
|
||||
|
||||
## Known Limitations and Caveats
|
||||
|
||||
### run_script_function Test Failure
|
||||
|
||||
The "Run Function" test will fail with a 404 error unless you manually configure the script as an API Executable. This is a Google platform requirement, not a bug.
|
||||
|
||||
To make run_script_function work:
|
||||
|
||||
1. Open the created test script in Apps Script editor
|
||||
2. Go to Project Settings > Change GCP project
|
||||
3. Enter your GCP project number
|
||||
4. Deploy as "API Executable"
|
||||
|
||||
For E2E testing purposes, it is acceptable for this test to fail. All other tests should pass.
|
||||
|
||||
### Drive API Requirement
|
||||
|
||||
The `list_script_projects` function uses the Google Drive API (not the Apps Script API) because the Apps Script API does not provide a projects.list endpoint. Ensure the Drive API is enabled in your GCP project.
|
||||
|
||||
### Scope Requirements
|
||||
|
||||
The E2E tests require these scopes:
|
||||
- `script.projects` and `script.projects.readonly`
|
||||
- `script.deployments` and `script.deployments.readonly`
|
||||
- `script.processes`
|
||||
- `drive.readonly`
|
||||
|
||||
If you encounter "insufficient scopes" errors, delete the stored token file and re-authenticate.
|
||||
|
||||
### Rate Limits
|
||||
|
||||
Google enforces rate limits on the Apps Script API. If running tests repeatedly, you may encounter quota errors. Wait a few minutes before retrying.
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
For automated testing in CI/CD pipelines:
|
||||
|
||||
### Unit Tests Only (Recommended)
|
||||
|
||||
```yaml
|
||||
# GitHub Actions example
|
||||
- name: Run unit tests
|
||||
run: uv run pytest tests/gappsscript/test_apps_script_tools.py -v
|
||||
```
|
||||
|
||||
### E2E Tests in CI
|
||||
|
||||
E2E tests require OAuth credentials. Options:
|
||||
|
||||
1. **Skip E2E in CI** - Run only unit tests in CI, run E2E locally
|
||||
2. **Service Account** - Not supported (Apps Script API requires user OAuth)
|
||||
3. **Pre-authenticated Token** - Store encrypted token in CI secrets
|
||||
|
||||
To use a pre-authenticated token:
|
||||
```bash
|
||||
# Generate token locally
|
||||
python tests/gappsscript/manual_test.py
|
||||
|
||||
# Store test_token.pickle contents as base64 in CI secret
|
||||
base64 test_token.pickle > token.b64
|
||||
|
||||
# In CI, restore and set path
|
||||
echo $TOKEN_SECRET | base64 -d > test_token.pickle
|
||||
export GOOGLE_TOKEN_PATH=./test_token.pickle
|
||||
python tests/gappsscript/manual_test.py --yes
|
||||
```
|
||||
|
||||
Note: Tokens expire and must be refreshed periodically.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Apps Script API has not been used in project"
|
||||
|
||||
Enable the Apps Script API in your GCP project:
|
||||
https://console.cloud.google.com/flows/enableapi?apiid=script.googleapis.com
|
||||
|
||||
### "Access Not Configured. Drive API has not been used"
|
||||
|
||||
Enable the Drive API in your GCP project:
|
||||
https://console.cloud.google.com/flows/enableapi?apiid=drive.googleapis.com
|
||||
|
||||
### "Request had insufficient authentication scopes"
|
||||
|
||||
Delete the token file and re-authenticate:
|
||||
```bash
|
||||
rm test_token.pickle
|
||||
python tests/gappsscript/manual_test.py
|
||||
```
|
||||
|
||||
### "User is not authorized to access this resource"
|
||||
|
||||
Ensure your email is added as a test user in the OAuth consent screen configuration.
|
||||
|
||||
### "Requested entity was not found" (404 on run)
|
||||
|
||||
The script needs to be deployed as "API Executable". See the run_script_function section above.
|
||||
|
||||
### OAuth redirect fails on headless machine
|
||||
|
||||
The redirect to `http://localhost` is expected to fail. Copy the URL from the browser address bar (including the error page URL) and paste it into the terminal.
|
||||
Reference in New Issue
Block a user