Skip to content

CLI Integration tests#165

Merged
DerekAgility merged 1 commit into
mainfrom
dlo/integration-tests
Jun 17, 2026
Merged

CLI Integration tests#165
DerekAgility merged 1 commit into
mainfrom
dlo/integration-tests

Conversation

@DerekAgility

@DerekAgility DerekAgility commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Adds integration scenario tests for the cli pipeline

What this is

A fixture-driven integration test runner under src/tests/sync/ that exercises the actual CLI sync pipeline against on-disk scenario state. Sixteen scenarios cover the main code paths for content items, models, and containers — each one represents a real-world condition (fresh sync, re-sync, conflicts, missing target files, selective sync via --models-with-deps, etc.).

These complement the existing unit tests: unit tests verify individual functions in isolation; scenarios verify the orchestration chain end-to-end.

What's "real" vs what's mocked

Real (not mocked):

  • All push logic — ContentBatchProcessor, pushModels, pushContainers, filterContentItemsForProcessing, change-detection, mappers
  • The ModelDependencyTreeBuilder (for selective-sync scenarios)
  • File operations against a real temp directory
  • Mapping file reads/writes through the actual fileOperations class

Mocked at the network boundary:

  • apiClient.contentMethods.saveContentItems
  • apiClient.modelMethods.saveModel
  • apiClient.containerMethods.saveContainer
  • pollBatchUntilComplete / extractContentBatchResults

The mock (helpers/mock-api-client.ts) captures every API call's payload and returns deterministic new IDs (e.g., new content items get target IDs starting at 9001, new models at 7001, new containers at 8001). This lets scenarios assert exactly which payloads were sent and which mappings landed on disk, without needing a live Agility instance.

How a scenario works

Each scenario is a directory under src/tests/sync/scenarios/:

scenarios/
├── _base/                              ← shared fixtures (Post model + Posts container + default mappings)
├── 01-fresh-sync/
│   ├── scenario.json                   ← config + assertions
│   └── state/src-1/en-us/item/1000.json
├── 02-re-sync-no-changes/
│   ├── scenario.json
│   └── state/                          ← only the files that differ from _base
...

scenario.json declares:

  • Source/target GUIDs and locale
  • Optional base (shared fixtures to inherit from)
  • Optional pushes ("content" | "models" | "containers") and modelsWithDeps for selective sync
  • Optional state overrides (e.g., overwrite: true)
  • An expect block — number of API calls, expected mapping shape, duplicate-detection flag

At test time, the runner:

  1. Copies _base/ into a fresh temp directory (if the scenario opts in)
  2. Overlays the scenario's own state/ on top (scenario files override base)
  3. Points state.rootPath at that temp directory
  4. Runs the real push pipeline against it
  5. Reads the resulting mapping file from disk and asserts against scenario.json's expect block

What's enforced by each scenario

Scenario What it asserts
01 Fresh sync creates one mapping per source item
02 Re-sync with unchanged versions makes zero API calls (idempotency)
03 Overwrite + missing target file → reuse stale ID instead of duplicating (PR #135 regression test)
04 Source bumped → update via existing target ID
05 Both versions bumped → conflict, skip without overwrite
06 Conflict + overwrite → force update (PR #149 semantic)
07 Multi-locale: fr-ca push inherits target ID from existing en-us mapping
08 Empty source → pipeline short-circuits cleanly
09 --models-with-deps="Post" excludes unrelated Author items
10 Orphan item skipped mid-batch doesn't misalign survivor mappings (PROD-1024 regression)
11 Fresh model push (stub create + field update)
12 Model update via existing mapping
13 Custom model with name-match in target falls through silently (documents PR #147 behavior)
14 Target model edited locally → upstream sync skips (protects downstream edits)
15 Multi-batch content (batchSize: 2, 5 items → 3 batches)
16 Container creation via pushContainers

@DerekAgility DerekAgility force-pushed the dlo/integration-tests branch from 2bf77ed to 30cb649 Compare June 17, 2026 13:27
@DerekAgility DerekAgility requested review from 5PK and jules-exel June 17, 2026 16:46
@DerekAgility DerekAgility merged commit 84fb832 into main Jun 17, 2026
3 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