|
| 1 | +# CFN Synthesis Tests |
| 2 | + |
| 3 | +These tests verify that `serverless-appsync-plugin` generates the |
| 4 | +expected CloudFormation when applied to a variety of real-world |
| 5 | +configurations. They complement the unit tests in `src/__tests__/`: |
| 6 | + |
| 7 | +| Concern | Unit tests | CFN synthesis tests | |
| 8 | +| --------------------------------------------- | ------------------- | ------------------- | |
| 9 | +| Pure function logic | ✓ | | |
| 10 | +| Schema validation | ✓ | | |
| 11 | +| Type coercion | ✓ | | |
| 12 | +| Plugin lifecycle on a real `serverless.yml` | | ✓ | |
| 13 | +| Generated CloudFormation resources | partial (snapshots) | ✓ | |
| 14 | +| Feature combinations | | ✓ | |
| 15 | +| Example projects stay current with the plugin | | ✓ | |
| 16 | + |
| 17 | +## How it works |
| 18 | + |
| 19 | +Each test loads one of the example projects under [`../examples/`](../examples), |
| 20 | +runs `serverless package` to produce a CloudFormation template, and |
| 21 | +asserts on the generated resources. |
| 22 | + |
| 23 | +Critically, **these tests do not deploy anything to AWS** — they only |
| 24 | +exercise the synthesis path. That makes them fast (~3s per fixture), |
| 25 | +fork-safe (no AWS credentials required), and suitable to run on every |
| 26 | +PR. |
| 27 | + |
| 28 | +## Running locally |
| 29 | + |
| 30 | +```bash |
| 31 | +# Run all CFN synthesis tests |
| 32 | +npm run test:e2e |
| 33 | + |
| 34 | +# Run everything (unit + synthesis) |
| 35 | +npm run test:all |
| 36 | + |
| 37 | +# Run a single fixture |
| 38 | +npx jest --config jest.e2e.config.ts basic-api-key |
| 39 | +``` |
| 40 | + |
| 41 | +## Adding a new test |
| 42 | + |
| 43 | +1. Create a new example under `examples/<feature>/`: |
| 44 | + - `serverless.yml` — minimal configuration demonstrating the feature |
| 45 | + - `schema.graphql` — GraphQL schema (or multiple `.graphql` files) |
| 46 | + - Any handlers or resolver code the example needs |
| 47 | +2. Add an entry to [`../examples/README.md`](../examples/README.md) |
| 48 | +3. Create `e2e/<feature>.e2e.test.ts` using the helpers from `helpers/` |
| 49 | +4. Run `npm run test:e2e` to verify |
| 50 | + |
| 51 | +The example should be **runnable**: a user should be able to `cd` into |
| 52 | +it, run `serverless deploy` (with AWS credentials), and get a working |
| 53 | +AppSync API. That keeps the examples honest as documentation. |
| 54 | + |
| 55 | +## Helpers reference |
| 56 | + |
| 57 | +See `helpers/synthesize.ts` and `helpers/assertions.ts` for the full |
| 58 | +set of utilities. The common patterns: |
| 59 | + |
| 60 | +```typescript |
| 61 | +import { synthesize } from './helpers/synthesize'; |
| 62 | +import { |
| 63 | + expectAuthenticationType, |
| 64 | + expectDataSourceOfType, |
| 65 | + expectResourceWithProperties, |
| 66 | + findOneResourceByType, |
| 67 | + getGraphQlApi, |
| 68 | +} from './helpers/assertions'; |
| 69 | + |
| 70 | +describe('examples/my-feature', () => { |
| 71 | + let result: ReturnType<typeof synthesize>; |
| 72 | + |
| 73 | + beforeAll(() => { |
| 74 | + result = synthesize('examples/my-feature'); |
| 75 | + }); |
| 76 | + |
| 77 | + afterAll(() => { |
| 78 | + result.cleanup(); |
| 79 | + }); |
| 80 | + |
| 81 | + it('does the thing', () => { |
| 82 | + expectAuthenticationType(result.template, 'API_KEY'); |
| 83 | + }); |
| 84 | +}); |
| 85 | +``` |
| 86 | + |
| 87 | +## CI |
| 88 | + |
| 89 | +A dedicated `e2e` job in `.github/workflows/ci.yml` runs the full |
| 90 | +synthesis test suite on every PR and push to `master` or `alpha`. It |
| 91 | +runs after the unit-test matrix completes successfully (no point |
| 92 | +running E2E if unit tests already failed). |
0 commit comments