Skip to content

fix(resource-deleter): await integration teardown and self-heal setup - #63

Merged
ajimae merged 3 commits into
mainfrom
fix/integration-teardown
Sep 24, 2026
Merged

ajimae merged 3 commits into
mainfrom
fix/integration-teardown

Conversation

@ajimae

@ajimae ajimae commented Sep 24, 2026

Copy link
Copy Markdown
Member

The bug

packages/resource-deleter/test/integration/cli.spec.ts discarded the promise in its teardown:

afterAll(async () => {
  await Promise.each(Object.keys(resources), (name: MethodNames) => {
    clearData(apiConfig, name);      // no `return`
  });
}, 45000);

Promise.each therefore had nothing to await. Teardown resolved immediately while the deletes were still in flight, and Jest tore the process down mid-request, leaving fixtures behind in the shared test project.

The beforeAll directly above it returns correctly (return createData(...), line 64), as does the other teardown at line 278 — this one was the outlier.

Why it was not self-correcting

beforeAll seeded without clearing first, so once residue existed it was permanent. Every subsequent run died at fixture setup with:

BadRequest: A duplicate value '"fooCatKey"' exists for field 'key'.

Because the failure is in a before* hook, it cascades to every test in the suite — including should print the module version given the version flag, which never calls the API. That is why recent runs showed 23 failures across 3 suites with a single underlying cause.

The fix

  1. return the promise in afterAll so teardown actually completes.
  2. Clear before seeding in beforeAll, so an interrupted run heals itself on the next attempt. This mirrors what personal-data-erasure already does (await Promise.all([clearData(...)]) before creating).
  3. Setup timeout 30s → 60s to cover the added clear step.

Verification

  • yarn typecheck → exit 0
  • yarn lint → exit 0

The integration tests themselves need project credentials, which are only injected in CI, so they could not be exercised locally — CI on this PR is the real check.

Note

This fixes the leak going forward. Any fooCatKey category (and the published product behind Product cannot be deleted as long as it is published in a catalog) already stranded in the shared test project still needs a one-time manual purge, or the new clear-before-seed step will handle it on the first run — whichever lands first.

🤖 Generated with Claude Code

`afterAll` passed a callback to `Promise.each` that called `clearData`
without returning it, so nothing was awaited. Teardown resolved while
the deletes were still in flight and Jest tore the process down
mid-request, leaving fixtures behind in the shared test project.

Once leaked, the residue was permanent: `beforeAll` seeded without
clearing first, so every later run failed with

    BadRequest: A duplicate value '"fooCatKey"' exists for field 'key'

and that cascaded to every test in the suite, including ones that
never touch the API.

Return the promise so teardown actually completes, and clear before
seeding so the suite recovers on its own from an interrupted run --
the same pattern personal-data-erasure already uses. The setup timeout
goes to 60s to cover the added clear step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ajimae
ajimae requested a review from a team as a code owner September 24, 2026 14:51
@changeset-bot

changeset-bot Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d752dbd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

ajimae and others added 2 commits September 24, 2026 16:54
Awaiting the teardown exposed a second defect it had been hiding: the
clear loop walks resources in declaration order, but commercetools
refuses to delete a resource that is still referenced, so removing
product-types before products fails with

    Can not delete a product-type while it is referenced by at least
    one product

Previously those rejections were discarded along with the un-returned
promise, so the ordering was never exercised.

Extract a single `clearAllResources` helper that walks the keys in
reverse, removing dependents first -- the order the per-resource
delete tests already assume via `Object.keys(resources).reverse()`.
Teardown timeout matches setup at 60s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With teardown ordering fixed, the remaining failure was

    BadRequest: Product cannot be deleted as long as it is published
    in a catalog

`clearData` deleted by id without unpublishing, so any published
product survived cleanup and poisoned later runs. The deleter itself
already handles this (src/main.ts:117), but the test helper did not.

Unpublish first when `masterData.published` is set, then delete with
the bumped version. The unpublish overrides a built request rather
than calling `.post()`, because the update-action union across every
resource builder is too complex for TypeScript to represent -- the
same workaround src/main.ts uses.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ajimae
ajimae merged commit aff8263 into main Sep 24, 2026
10 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.

1 participant