This document outlines the plan for implementing unit and integration tests for the APODEmail-node repository, enabling local automation without GAE deployment.
- Test Runner: Vitest
- Modern, fast, and Jest-compatible API.
- Native support for ESM and TypeScript (though we are using CJS).
- Integration Testing: Supertest
- For testing Express routes without manually starting the server.
- Mocking:
vitestbuilt-in mocking for services and external APIs.sinon(optional) if more complex mocking is needed, but Vitest is usually sufficient.
- Logging:
- Keep using
pinobut silence it or set toERROR/SILENTduring tests unless debugging.
- Keep using
/test
├───integration/ # Integration tests (API routes, end-to-end)
│ └───routes.test.js
├───unit/ # Unit tests for individual components
│ ├───services/
│ │ ├───apodService.test.js
│ │ ├───emailService.test.js
│ │ └───statsService.test.js
│ └───database.test.js # Testing data access logic with Mocks
└───setup.js # Global test setup (env vars, global mocks)
apodService.js:- Mock
axiosto simulate NASA API responses (or the scraper). - Verify parsing of HTML/JSON.
- Test edge cases (missing data, video content vs image content).
- Mock
emailService.js:- Verify HTML templates are rendered correctly with provided data.
- Mock Cloud Tasks to ensure emails are correctly scheduled if applicable.
statsService.js:- Test calculation logic for signup counts, conversion rates, etc.
- Mock
@google-cloud/datastore. - Ensure
saveSubscriber,getSubscriber, and other DB methods call Datastore with correct parameters. - Test handling of "Not Found" or "Conflict" errors.
- Use
supertest(app)to hit endpoints. - Signup Flow:
- POST
/signupwith valid/invalid data. - Verify Datastore and Cloud Tasks are "called" (via mocks).
- Verify response codes and messages.
- POST
- Stats:
- GET
/statsand verify it returns correct rendered HTML or JSON.
- GET
- Verification:
- Simulate the verification redirect and ensure subscriber status updates.
- Install Dependencies:
npm install --save-dev vitest @vitest/coverage-v8 supertest
- Update
package.json:"scripts": { "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage" }
- Mock Environment:
- Use
MOCK_GCP=true(which seems to be partially implemented) to bypass actual GCP calls in local tests. - Use a
test/setup.jsto initialize environment variables for testing.
- Use
- Phase 1: Basic Setup
- Install dependencies and configure
package.json. - Create
test/setup.js.
- Install dependencies and configure
- Phase 2: Service Unit Tests
- Start with
statsService.jsandapodService.jsas they are more isolated.
- Start with
- Phase 3: Database Mocking
- Implement mocks for Datastore.
- Phase 4: Route Integration Tests
- Use
supertestto cover the main signup and stats flows.
- Use
- Phase 5: Automation
- Ensure
npm testruns smoothly and provides meaningful output.
- Ensure