Skip to content

Appending after an exhausted replay sequence can overwrite the base file #7

Description

@pikant

Context

Found while validating the EVOC migration against eyond/laravel-http-replay v0.2.2.

Replay correctly loads repeated responses as a queue using the base filename followed by __2, __3, and so on. When an existing queue is exhausted during a non-bail local run, the next real response should be appended to that sequence.

Reproduction

  1. A test directory already contains operation.json and operation__2.json.
  2. Activate Replay without bail or fresh mode.
  3. Send the matching request three times.
  4. The first two requests consume the stored responses.
  5. The third request falls through to the real client and is recorded.

Actual behavior

ReplayBuilder::loadStoredResponses loads the existing files into responseQueues, but it does not register their filenames in usedFilenames.

ReplayBuilder::handleResponseReceived later calls ReplayNamer::makeUnique using only usedFilenames from the current process. Because the existing stored filenames are absent, the new response can be stored as operation.json and overwrite the original base response.

Expected behavior

The newly recorded response is appended as operation__3.json. Existing sequence files remain unchanged.

Impact

This can silently replace the first response of a recorded sequence during local development. CI bail mode prevents the path in CI, and Git makes the change visible, but the recording behavior should still be lossless.

Suggested direction

  • Determine used filenames from the active save directory before recording, or make uniqueness checks include files already present there.
  • Consider readFrom and writeTo separately so only collisions in the save target affect the suffix.
  • Add a regression test with existing base and __2 files, exhaust both responses, record one additional response, and assert that base and __2 remain unchanged while __3 is created.

Fresh mode is not affected because it intentionally deletes the prior recordings before re-recording.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions