Skip to content

test: add 5 more CFN synthesis fixtures for previously-uncovered code…#707

Merged
sid88in merged 3 commits into
masterfrom
chore/cfn-synthesis-tests-batch-2
May 30, 2026
Merged

test: add 5 more CFN synthesis fixtures for previously-uncovered code…#707
sid88in merged 3 commits into
masterfrom
chore/cfn-synthesis-tests-batch-2

Conversation

@sid88in
Copy link
Copy Markdown
Owner

@sid88in sid88in commented May 29, 2026

test: add 5 more CFN synthesis fixtures for previously-uncovered code paths

What

Builds on the 24-fixture suite from #704 with 5 targeted additions that each
exercise a plugin code path the existing fixtures don't reach.

Test surface grows from 25 → 30 suites and 68 → 84 assertions.

Why these 5 specifically

I deliberately scoped this batch to uncovered code paths, not variations
on existing fixtures. Each new fixture targets a branch in the plugin source
that no existing test touches:

Fixture Code path it newly covers
sync-config-versioned SyncConfig block on resolvers + DynamoDB Versioned + DeltaSyncConfigsyncConfig.test.ts had unit coverage but zero synthesis coverage
custom-domain-no-cfn useCloudFormation: false branch in Api.ts (early return, no CFN domain resources emitted) — complements the existing custom-domain fixture which exercises the true branch
waf-pre-existing-arn waf.arn branch in Waf.ts (emits only WebACLAssociation, skips WebACL creation entirely) — complements the existing waf fixture
pipeline-resolver-with-code Pipeline resolver with its own top-level code: (before/after handlers) — the existing pipeline-resolvers fixture only exercises per-function code
api-key-import-existing apiKeyId field on API key config (CFN ApiKeyId pass-through) for stable migrations / blue-green deploys

What I deliberately did NOT add

To avoid procrastination-via-tests, I rejected fixtures that would only
exercise variation, not new code paths:

  • More auth combinations (multi-auth already exercises the union path)
  • More data source types (all 7 AppSync types now covered)
  • Various caching TTL values (same code path)
  • Logging at different levels (same code path)
  • Cognito + Lambda authorizer multi-auth combo (same union path as multi-auth)

After this batch, I'd argue the synthesis test suite is materially complete.
Future fixtures should be added alongside the feature work that needs them
(e.g. when MERGED API support lands, add a merged-api fixture in that PR).

Real plugin behavior caught while building

While writing sync-config-versioned I found that the plugin silently
ignores versioned: true
on a DynamoDB data source unless deltaSyncConfig
is also configured. The CFN output omits the Versioned attribute entirely
in that case. The fixture deliberately demonstrates the combination that
works so users don't hit this gotcha.

Not changing plugin behavior in this PR — that's a separate question (is
this validation-warning territory, or just a docs note?). Filing it as an
observation worth knowing.

Verification

  • npm run test — 288 unit tests pass
  • npm run test:e2e — 84 assertions across 30 suites pass (~85s)
  • npm run lint — clean (0 errors, 0 warnings)
  • npm run build — clean

Out of scope (follow-ups for future PRs)

Summary by CodeRabbit

  • New Features

    • Added five example projects: API-key import/rotation, custom domain without CloudFormation, pipeline resolvers with inline code, versioned sync with conflict handling, and WAF using a pre-existing ARN.
  • Tests

    • Added end-to-end tests that synthesize each example and validate generated infrastructure and resolver behavior.
  • Documentation

    • Updated the examples index to include and describe the new projects.

Review Change Stack

… paths

Builds on the 24-fixture suite from #704. Each new fixture targets a
specific plugin code path that the existing fixtures don't exercise:

- sync-config-versioned (3 tests): DynamoDB conflict resolution with
  OPTIMISTIC_CONCURRENCY and AUTOMERGE handlers, plus delta sync table
  configuration for offline-capable mobile apps. Closes a gap where
  syncConfig.test.ts had unit coverage but no synthesis coverage.

- custom-domain-no-cfn (5 tests): The useCloudFormation: false code
  path on the domain config. Asserts the absence of CFN resources
  (DomainName, DomainNameApiAssociation, RecordSet, Certificate) that
  the useCloudFormation: true variant DOES create. Complements the
  existing custom-domain fixture.

- waf-pre-existing-arn (2 tests): WAF attached via an existing ACL ARN
  rather than created inline via rules. Different code path in Waf.ts
  that emits only WebACLAssociation, not WebACL. Complements the
  existing waf fixture.

- pipeline-resolver-with-code (3 tests): A pipeline resolver with its
  own top-level JS code (before/after handlers) in addition to per-
  function code. Different from the existing pipeline-resolvers fixture
  which only has function-level code.

- api-key-import-existing (3 tests): Importing an existing API key via
  apiKeyId for stable migrations / blue-green deploys, alongside an
  auto-generated key. Verifies ApiKeyId is passed through faithfully.

Test surface grows from 25 -> 30 suites and 68 -> 84 assertions.

Real plugin behavior caught while building the fixtures:
- DataSource config 'versioned: true' is silently ignored unless
  'deltaSyncConfig' is ALSO provided. Without delta sync config, the
  CFN output omits the Versioned attribute entirely. Worth noting in
  docs eventually, but not breaking — included both in this fixture
  to demonstrate the combination that actually works.
@sid88in sid88in requested a review from AlexHladin May 29, 2026 01:44
Comment thread e2e/api-key-import-existing.e2e.test.ts Outdated
const keys = findResourcesByType(result.template, 'AWS::AppSync::ApiKey');
const stable = keys.find(
(k) =>
(k.resource.Properties?.Description as string) ===
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

type cast is not needed here

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

fixed

Comment thread e2e/api-key-import-existing.e2e.test.ts Outdated
const keys = findResourcesByType(result.template, 'AWS::AppSync::ApiKey');
const rotating = keys.find(
(k) =>
(k.resource.Properties?.Description as string) ===
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

type cast is not needed here

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

fixed

@sid88in
Copy link
Copy Markdown
Owner Author

sid88in commented May 29, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 71e0560e-6caa-4247-b824-6853367406d8

📥 Commits

Reviewing files that changed from the base of the PR and between fa71f7b and 91a4916.

📒 Files selected for processing (1)
  • examples/pipeline-resolver-with-code/functions/fetchProfile.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/pipeline-resolver-with-code/functions/fetchProfile.js

📝 Walkthrough

Walkthrough

Adds five AppSync example projects (api-key-import-existing, custom-domain-no-cfn, waf-pre-existing-arn, pipeline-resolver-with-code, sync-config-versioned) with GraphQL schemas, Serverless configs, and e2e Jest tests; updates examples README.

Changes

Five new AppSync example projects with tests

Layer / File(s) Summary
API Key Import example: schema and dual-key configuration
examples/api-key-import-existing/schema.graphql, examples/api-key-import-existing/serverless.yml
Simple Query schema paired with serverless configuration defining two API keys: one with explicit apiKeyId for migration/retention, one newly generated without ID.
API Key Import e2e test
e2e/api-key-import-existing.e2e.test.ts
Test synthesizes the example and asserts two API key resources created, stable key preserving ID, rotating key omitting ID.
Custom Domain (no CloudFormation) example
examples/custom-domain-no-cfn/schema.graphql, examples/custom-domain-no-cfn/serverless.yml
Query schema with serverless configuration enabling custom domain routing while disabling CloudFormation domain resource creation for externally-managed domains.
Custom Domain e2e test
e2e/custom-domain-no-cfn.e2e.test.ts
Test synthesizes the example and verifies GraphQL API creation while confirming domain-related resources (DomainName, Route53, Certificate Manager) are absent.
WAF pre-existing ARN example
examples/waf-pre-existing-arn/schema.graphql, examples/waf-pre-existing-arn/serverless.yml
Query schema with serverless configuration enabling WAF by importing an existing WebACL ARN via CloudFormation Fn::ImportValue, without creating new WebACL.
WAF pre-existing ARN e2e test
e2e/waf-pre-existing-arn.e2e.test.ts
Test synthesizes the example and asserts zero WebACL resources while confirming WebACLAssociation references the imported ARN.
Sync Config Versioned example: schema and configuration
examples/sync-config-versioned/schema.graphql, examples/sync-config-versioned/serverless.yml
Post type with version field and updatePost/mergePost mutations, configured with VERSION conflict detection, different conflict handlers (OPTIMISTIC_CONCURRENCY vs AUTOMERGE), and delta sync table.
Sync Config Versioned e2e test
e2e/sync-config-versioned.e2e.test.ts
Test synthesizes the example and validates resolver conflict detection strategies, versioned DynamoDB data source configuration, and delta sync settings with TTL.
Pipeline Resolver example: schema and types
examples/pipeline-resolver-with-code/schema.graphql
User type with optional profile reference, Profile type with metadata fields, and getUserDetails query accepting user ID.
Pipeline Resolver example: function handlers and resolver
examples/pipeline-resolver-with-code/functions/fetchUser.js, examples/pipeline-resolver-with-code/functions/fetchProfile.js, examples/pipeline-resolver-with-code/resolvers/getUserDetails.js
FetchUser and fetchProfile pipeline functions querying DynamoDB, with getUserDetails top-level resolver validating arguments and chaining the function sequence.
Pipeline Resolver example: serverless configuration
examples/pipeline-resolver-with-code/serverless.yml
Serverless configuration defining pipeline resolver with inline code support, chaining functions, DynamoDB data sources, and provisioning UsersTable and ProfilesTable.
Pipeline Resolver e2e test
e2e/pipeline-resolver-with-code.e2e.test.ts
Test synthesizes the example and validates pipeline resolver with inline Code and APPSYNC_JS Runtime, two function configurations with matching Code/Runtime, and PipelineConfig referencing both functions.
Documentation: examples README index
examples/README.md
Examples README index table expanded to include all five new examples with descriptions and links.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Five examples hop into view,
Schemas, configs, tests brand-new,
Keys to import, domains to route,
Pipeline functions trace the route,
Versioning keeps conflicts cool! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adding 5 new e2e test fixtures to cover previously-untested CloudFormation synthesis code paths.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/cfn-synthesis-tests-batch-2

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
examples/custom-domain-no-cfn/serverless.yml (1)

33-34: 💤 Low value

Consider simplifying certificateArn to a plain string.

Since useCloudFormation: false, the certificate ARN is metadata for CLI commands rather than a CloudFormation template value. Using Fn::Sub with pseudo-parameters (${AWS::Partition}, ${AWS::AccountId}) adds unnecessary complexity for a test fixture where these won't be resolved in the CFN output.

♻️ Suggested simplification
-    certificateArn:
-      Fn::Sub: 'arn:${AWS::Partition}:acm:us-east-1:${AWS::AccountId}:certificate/abc-123'
+    certificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/abc-123'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/custom-domain-no-cfn/serverless.yml` around lines 33 - 34, Replace
the Fn::Sub expression used for certificateArn with a plain string literal since
this stack uses useCloudFormation: false; locate the certificateArn key
(currently set to Fn::Sub:
'arn:${AWS::Partition}:acm:us-east-1:${AWS::AccountId}:certificate/abc-123') and
change it to a simple ARN string (e.g.,
'arn:aws:acm:us-east-1:123456789012:certificate/abc-123') so CLI tooling
receives a concrete value without CloudFormation pseudo-parameters.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/pipeline-resolver-with-code/functions/fetchProfile.js`:
- Around line 3-7: In fetchProfile.request, guard against a missing previous
result by checking ctx.prev.result (and/or ctx.prev.result.id) before
constructing the DynamoDB key; if it's null/undefined, return an explicit
not-found/short-circuit response (e.g. a step that returns or signals no item)
instead of accessing ctx.prev.result.id, otherwise proceed to build the GetItem
operation and key as currently done. Ensure the change is made in the request
function for fetchProfile so downstream code won't throw on a null
ctx.prev.result.

In `@examples/sync-config-versioned/serverless.yml`:
- Around line 53-81: Add Point-In-Time Recovery to both DynamoDB table resources
by updating the PostsTable and PostsDeltaTable Properties to include
PointInTimeRecoverySpecification with PointInTimeRecoveryEnabled: true;
specifically, modify the PostsTable resource and the PostsDeltaTable resource
(which currently has TimeToLiveSpecification) to each include
PointInTimeRecoverySpecification: { PointInTimeRecoveryEnabled: true } so PITR
is enabled for both tables.

---

Nitpick comments:
In `@examples/custom-domain-no-cfn/serverless.yml`:
- Around line 33-34: Replace the Fn::Sub expression used for certificateArn with
a plain string literal since this stack uses useCloudFormation: false; locate
the certificateArn key (currently set to Fn::Sub:
'arn:${AWS::Partition}:acm:us-east-1:${AWS::AccountId}:certificate/abc-123') and
change it to a simple ARN string (e.g.,
'arn:aws:acm:us-east-1:123456789012:certificate/abc-123') so CLI tooling
receives a concrete value without CloudFormation pseudo-parameters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82fc61e2-8208-447a-89da-507545b97388

📥 Commits

Reviewing files that changed from the base of the PR and between bda9abe and fa71f7b.

📒 Files selected for processing (19)
  • e2e/api-key-import-existing.e2e.test.ts
  • e2e/custom-domain-no-cfn.e2e.test.ts
  • e2e/pipeline-resolver-with-code.e2e.test.ts
  • e2e/sync-config-versioned.e2e.test.ts
  • e2e/waf-pre-existing-arn.e2e.test.ts
  • examples/README.md
  • examples/api-key-import-existing/schema.graphql
  • examples/api-key-import-existing/serverless.yml
  • examples/custom-domain-no-cfn/schema.graphql
  • examples/custom-domain-no-cfn/serverless.yml
  • examples/pipeline-resolver-with-code/functions/fetchProfile.js
  • examples/pipeline-resolver-with-code/functions/fetchUser.js
  • examples/pipeline-resolver-with-code/resolvers/getUserDetails.js
  • examples/pipeline-resolver-with-code/schema.graphql
  • examples/pipeline-resolver-with-code/serverless.yml
  • examples/sync-config-versioned/schema.graphql
  • examples/sync-config-versioned/serverless.yml
  • examples/waf-pre-existing-arn/schema.graphql
  • examples/waf-pre-existing-arn/serverless.yml

Comment thread examples/pipeline-resolver-with-code/functions/fetchProfile.js
Comment thread examples/sync-config-versioned/serverless.yml
@sid88in sid88in merged commit 082c00b into master May 30, 2026
6 checks passed
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