Zenodo Sandbox Testing
This guide explains how to test DOI creation workflows using the Zenodo sandbox environment.
Table of Contents
Section titled “Table of Contents”- What is Zenodo Sandbox?
- When to Use Sandbox
- Setup
- Running Tests
- CLI Sandbox Mode
- Test Data Management
- Test Coverage
- Rate Limits
- Troubleshooting
- Webhook Testing
- References
What is Zenodo Sandbox?
Section titled “What is Zenodo Sandbox?”Zenodo provides a sandbox environment (sandbox.zenodo.org) separate from production for testing DOI workflows. Key characteristics:
- Separate infrastructure: Completely isolated from production Zenodo
- Test DOIs: DOIs are created in sandbox registry (not indexed by DataCite)
- No production impact: Actions in sandbox never affect production
- DOIs are permanent: Once published, even sandbox DOIs cannot be deleted
- Same API: Identical API to production, different base URL
Important: Sandbox DOIs do NOT resolve via doi.org because they are not registered with DataCite. Use Zenodo’s sandbox URL directly.
When to Use Sandbox
Section titled “When to Use Sandbox”Use the sandbox for:
- ✅ Testing DOI creation workflows
- ✅ Developing new DOI-related features
- ✅ Running automated tests in CI/CD
- ✅ Learning Zenodo API without production side effects
- ✅ Verifying metadata formatting before production
Do NOT use sandbox for:
- ❌ Real dataset publication (DOIs won’t resolve)
- ❌ Testing DataCite integration (sandbox doesn’t register with DataCite)
- ❌ Permanent archival (sandbox may be reset periodically)
1. Get Sandbox API Token
Section titled “1. Get Sandbox API Token”- Go to sandbox.zenodo.org
- Create an account (separate from production Zenodo)
- Navigate to Account Settings > Applications > Personal access tokens
- Create new token with
deposit:writeanddeposit:actionsscopes - Save the token securely
2. Configure Environment
Section titled “2. Configure Environment”Create or update test/.env.test:
# Required for Zenodo testsZENODO_SANDBOX_API_KEY=your_sandbox_token_hereRUN_ZENODO_TESTS=trueTEST_DATASET_ID=nm099999
# Admin credentials (from backend team)TEST_ADMIN_API_KEY=your_admin_keyTEST_API_URL=https://nemar-api-dev.sccn-org.workers.devSecurity notes:
- Never commit
.env.testto git (already in.gitignore) - Never use production Zenodo token for sandbox tests
- Keep sandbox token separate from production token
Running Tests
Section titled “Running Tests”Local Testing
Section titled “Local Testing”Run Zenodo sandbox tests:
# All sandbox testsRUN_ZENODO_TESTS=true TEST_DATASET_ID=nm099999 bun test test/zenodo-sandbox.test.ts
# Specific test suiteRUN_ZENODO_TESTS=true TEST_DATASET_ID=nm099999 bun test test/zenodo-sandbox.test.ts -t "Metadata Updates"Note: Tests are skipped by default unless RUN_ZENODO_TESTS=true to prevent accidental sandbox usage.
CI/CD Testing
Section titled “CI/CD Testing”Tests run automatically on:
- Pull requests that modify
backend/ortest/files - Pushes to
mainordevbranches
CI workflow uses GitHub Secrets:
ZENODO_SANDBOX_API_KEY: Sandbox API token (admin must configure)TEST_ADMIN_API_KEY: Backend admin credentials
View test results:
gh run list --workflow=test.yml --limit 5gh run view --logCLI Sandbox Mode
Section titled “CLI Sandbox Mode”The CLI supports sandbox mode for testing DOI creation without affecting production:
Create Sandbox Concept DOI
Section titled “Create Sandbox Concept DOI”nemar admin doi create nm099999 \ --sandbox \ --title "Test Dataset" \ --description "Testing DOI workflow"CLI will display:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SANDBOX MODE ENABLED━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Using Zenodo sandbox (sandbox.zenodo.org) • DOI will NOT be indexed by DataCite • DOI will NOT resolve in production • Use this for testing workflows only━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━View Sandbox DOI Info
Section titled “View Sandbox DOI Info”nemar admin doi info nm099999Sandbox DOIs are detected and labeled:
Mode: SANDBOX (test DOI) This DOI is not indexed by DataCite and will not resolve in productionTest Data Management
Section titled “Test Data Management”Disposable Test Dataset
Section titled “Disposable Test Dataset”Tests use nm099999 as the standard test dataset:
- Already registered in D1 database
- Already has GitHub repository
- Designated for testing purposes
- Data can be safely modified/deleted
Deposition Cleanup
Section titled “Deposition Cleanup”Test suite automatically cleans up unpublished depositions after tests complete:
afterAll(async () => { // Deletes all unpublished depositions created during tests // Published depositions are permanent and cannot be deleted});Important: Published sandbox DOIs are permanent and accumulate over time. This is by design (Zenodo does not allow DOI deletion).
Avoiding Data Pollution
Section titled “Avoiding Data Pollution”- Use timestamped titles:
Test Dataset ${Date.now()} - Limit published depositions (most tests use drafts only)
- Track created depositions in
createdDepositionsarray - Delete unpublished drafts in cleanup
Test Coverage
Section titled “Test Coverage”The test suite covers 7 major areas:
1. Concept DOI Creation (Sandbox)
Section titled “1. Concept DOI Creation (Sandbox)”- ✓ Create concept DOI on sandbox
- ✓ Retrieve DOI info
- ✓ Block production DOI in dev environment
2. Version DOI Publishing (Sandbox)
Section titled “2. Version DOI Publishing (Sandbox)”- ✓ Webhook token validation
- ✓ Sandbox flag enforcement
3. Metadata Updates (Sandbox)
Section titled “3. Metadata Updates (Sandbox)”- ✓ Update title and description
- ✓ Update keywords and license
- ✓ Add related identifiers
4. Error Handling (Sandbox)
Section titled “4. Error Handling (Sandbox)”- ✓ Invalid API token (401)
- ✓ Invalid deposition ID (404)
- ✓ Publishing already-published (400)
- ✓ Missing required metadata (400)
5. Rate Limiting (Sandbox)
Section titled “5. Rate Limiting (Sandbox)”- ✓ Respect rate limits with delays
- ✓ Handle 429 responses gracefully
6. Deposition Lifecycle (Sandbox)
Section titled “6. Deposition Lifecycle (Sandbox)”- ✓ Create → upload → publish workflow
- ✓ Create → update metadata → publish
- ✓ Create new version from published
- ✓ Delete unpublished drafts
7. File Upload (Sandbox)
Section titled “7. File Upload (Sandbox)”- ✓ Upload single file
- ✓ Upload multiple files
- ✓ Verify file checksums
- ✓ Handle large file upload (1MB)
Rate Limits
Section titled “Rate Limits”Zenodo enforces rate limits to protect the service:
Limits
Section titled “Limits”- Sandbox: 60 requests per minute minimum (1 request per second)
- Production: 100 requests per minute (authenticated)
Best Practices
Section titled “Best Practices”- Minimum delay: 1000ms (60 req/min = 1 req/sec)
- Recommended delay: 400-500ms provides safety margin (120-150 req/min max)
- Use exponential backoff for retries
- Respect 429 (Too Many Requests) responses
Why 400ms instead of 1000ms? The test suite uses 400ms delays to provide a safety buffer. While the documented limit is 60 req/min (1000ms), using 400ms allows ~150 req/min maximum, which accounts for:
- Request processing time variations
- Network latency
- Other concurrent API calls
- Potential rate limit enforcement variations
Test Implementation
Section titled “Test Implementation”// Using 400ms delays (safety margin above 60 req/min minimum)await sleep(400);
// Rate limit handling with exponential backoffif (response.status === 429) { const retryAfter = response.headers.get("Retry-After"); await sleep(Number.parseInt(retryAfter || "60") * 1000); // Retry request}Troubleshooting
Section titled “Troubleshooting”Tests Skipped
Section titled “Tests Skipped”Problem: Tests show “Skipping: RUN_ZENODO_TESTS not set”
Solution: Set environment variable:
RUN_ZENODO_TESTS=true bun test test/zenodo-sandbox.test.tsToken Not Configured
Section titled “Token Not Configured”Problem: Tests skip with “ZENODO_SANDBOX_API_KEY not set”
Solution: Add token to test/.env.test:
ZENODO_SANDBOX_API_KEY=your_sandbox_tokenProduction Token Detected
Section titled “Production Token Detected”Problem: Error “DANGER: Test configured with production token!”
Solution: Ensure ZENODO_SANDBOX_API_KEY is different from ZENODO_API_KEY:
ZENODO_SANDBOX_API_KEY=sandbox_token_here # ✓ Correct
# Do NOT do this:# ZENODO_SANDBOX_API_KEY=$ZENODO_API_KEY # ✗ Wrong401 Unauthorized
Section titled “401 Unauthorized”Problem: Tests fail with 401 status
Causes:
- Invalid or expired sandbox token
- Token doesn’t have required scopes
Solution:
- Verify token on sandbox.zenodo.org
- Check token has
deposit:writeanddeposit:actionsscopes - Generate new token if expired
404 Not Found
Section titled “404 Not Found”Problem: Dataset nm099999 not found
Solution: Ensure test dataset is registered:
# Contact admin to verify nm099999 exists in dev database# Or use different test dataset IDTEST_DATASET_ID=nm000XXX bun test test/zenodo-sandbox.test.ts429 Rate Limited
Section titled “429 Rate Limited”Problem: Tests fail with “Too Many Requests”
Solution: Increase delays between requests:
await sleep(500); // Increase from 300ms to 500msCI Tests Failing
Section titled “CI Tests Failing”Problem: Tests pass locally but fail in CI
Causes:
- GitHub secret not configured
- Wrong environment URL
Solution:
- Verify
ZENODO_SANDBOX_API_KEYexists in GitHub Secrets - Check workflow uses correct API URL (dev, not prod)
Webhook Testing
Section titled “Webhook Testing”Webhook endpoint tests verify GitHub Actions can trigger version DOI creation:
Webhook Flow
Section titled “Webhook Flow”- User creates GitHub release
- GitHub Actions workflow triggers
- Workflow calls webhook:
/webhooks/publish-version-doi - Backend creates new version DOI on Zenodo
- Backend updates dataset metadata in D1
Test Coverage
Section titled “Test Coverage”- ✓ Invalid webhook token rejected (401)
- ✓ Sandbox flag required for test datasets
Manual Testing
Section titled “Manual Testing”curl -X POST https://nemar-api-dev.sccn-org.workers.dev/webhooks/publish-version-doi \ -H "Content-Type: application/json" \ -H "X-Webhook-Token: test_token" \ -d '{ "dataset_id": "nm099999", "version": "1.0.0", "release_url": "https://github.com/nemarDatasets/nm099999/releases/tag/v1.0.0", "sandbox": true }'References
Section titled “References”- Zenodo Sandbox
- Zenodo API Documentation
- Zenodo REST API
- DataCite DOI Registration
- NEMAR API Reference