[AB-2620] feature/added example key matching#950
Open
AyushShri wants to merge 5 commits into
Open
Conversation
Contributor
unit test code coverage
Coverage Breakdown • (89%)
|
Contributor
integration test code coverage
Coverage Breakdown • (20%)
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the OpenAPI → Postman collection conversion logic to emit multiple saved responses when request/response examples share the same example key, while preserving deterministic behavior by falling back to the legacy “first request + first response” path when no keys match.
Changes:
- Updated example pairing logic to match request/response examples strictly by shared example key name (case-insensitive), otherwise fall back to first-only (no positional matching).
- Updated response generation to emit one Postman saved response per matched example pair for a given status code.
- Added/updated unit tests (with and without type extraction) to cover matching-key pairing and fallback behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
libV2/CollectionGeneration/schemaUtils.js |
Implements matching-key pairing for examples, removes positional matching behavior, and emits multiple saved responses per status code where applicable. |
test/unit/convertV2.test.js |
Updates/extends convertV2 unit tests to assert multi-example pairing by key and first-only fallback when no keys match. |
test/unit/convertV2WithTypes.test.js |
Adds coverage for matching-key pairing and first-only fallback while asserting extracted types remain correct. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
1485
to
1490
| const matchedKeys = _.intersectionBy(responseExampleKeys, requestBodyExampleKeys, _.toLower), | ||
| isResponseCodeMatching = false; | ||
|
|
||
| // Only match in case of default response example matching with any request body example | ||
| if (!matchedKeys.length && responseExamples.length === 1 && responseExamples[0].key === '_default') { | ||
| const responseCodes = _.map(responseExamples, 'responseCode'); | ||
|
|
||
| matchedKeys = _.intersectionBy(responseCodes, requestBodyExampleKeys, _.toLower); | ||
| isResponseCodeMatching = matchedKeys.length > 0; | ||
| } | ||
|
|
||
| // Do keys matching first and ignore any leftover req/res body for which matching is not found | ||
| if (matchedKeys.length) { | ||
| _.forEach(matchedKeys, (key) => { |
…r non-first responses.
Comment on lines
+99
to
+103
| // Index existing responses by status code, keeping the FIRST occurrence per code so the | ||
| // request example maps to the first saved response of a code; the rest are left untouched. | ||
| currentRequest.responses.each((response) => { | ||
| currentResponses[response.code] = response; | ||
| if (!currentResponses[response.code]) { | ||
| currentResponses[response.code] = response; |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
animeshjajoopostman
approved these changes
Jun 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When converting a spec to a collection, pair a request example with a response example when they share the same example key name, and emit one Postman saved response per matched key — instead of collapsing everything to the first example. When nothing matches, fall back to the legacy first-request + first-response behavior (zero regression).
Problem
An OpenAPI operation can define multiple named examples for a request body and for each response (e.g. an admin example and a user example). Today, when we convert a spec to a Postman collection — and sync it back — we keep only the first example and drop the rest.
This was an intentional earlier decision: OpenAPI doesn't define any relationship or ordering between a request example and a response example, so automatically pairing them was a guess that could change between runs and broke 2-way sync. To stay safe, we collapsed everything to the first example.
A customer now needs all of their examples to come through. So we need to surface multiple examples without reintroducing that non-determinism — the spec ↔ collection round trip must stay deterministic and lossless (syncing one direction and back must reconstruct the original).
Approach:
pair a request example with a response example only when they share the same example key name (e.g. both called admin). Matched pairs become separate saved responses in the collection; anything unmatched falls back to today's "first example" behavior. This keeps the mapping explicit and reversible.
This is the forward (spec → collection) half of multi-example round-trip support; the reverse half lives in
@postman/collection-to-openapiPR.What changed (
libV2/CollectionGeneration/schemaUtils.js)(operation, statusCode): compute the matching keys between the request examples and that code's response examples. For each matched key, emit a saved response withresponse.body= the response example andoriginalRequest.body= the matched request example.descriptionon sync. Pairing identity rides on the example key, not the name.Scope / non-goals
originalRequest.Tests
test/unit/convertV2.test.js— updated the multi-example cases to the matching-key behavior; added "falls back to first request and first response example when no request/response keys match".test/unit/convertV2WithTypes.test.js— added a matching-key test and a fallback test (also asserting type extraction).Fixes:
AB-2620 https://postmanlabs.atlassian.net/browse/AB-2620
Test plan
npm run test-unit(convertV2, convertV2WithTypes, CollectionGenerationAndSyncing) — green