Skip to content

Commit 4a910a5

Browse files
committed
fix: operation matching when operation base path moved between path and path item servers object when comparing prefix groups
1 parent 0bd030d commit 4a910a5

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

src/apitypes/rest/rest.changes.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,23 +278,37 @@ export function createCopyWithEmptyPathItems(template: RestOperationData): RestO
278278
}
279279

280280
export function createCopyWithCurrentGroupOperationsOnly(template: RestOperationData, group: string): RestOperationData {
281-
const { paths, ...rest } = template
281+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
282+
const { paths, servers: rootServers, ...rest } = template
282283
const groupWithoutEdgeSlashes = trimSlashes(group)
283284

284-
if (trimSlashes(getOperationBasePath(template.servers)) === groupWithoutEdgeSlashes) {
285-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
286-
const { servers, ...rest } = template
287-
return { ...rest }
288-
}
289-
285+
// Since we are anyway composing synthetic specs for prefix groups comparison, we can incorporate
286+
// base paths from root servers and path item servers into the paths.
287+
// We also remove servers objects, since changes in servers for prefix groups are not relevant.
288+
// Note that servers in operation objects are not taken into account
289+
// (it is impossible to support them in api-diff mapping
290+
// and they are considered bad practice on OpenAPI specifications anyway)
290291
return {
291292
paths: {
292293
...Object.fromEntries(
293294
Object.entries(paths)
294-
.filter(([key]) => removeFirstSlash(key).startsWith(`${groupWithoutEdgeSlashes}/`)) // note that 'api/v10' is a substring of 'api/v1000'
295+
.map(([pathKey, pathItem]) => {
296+
// Path item servers take precedence over root servers
297+
const pathItemServers = (pathItem as OpenAPIV3.PathItemObject)?.servers
298+
const basePath = getOperationBasePath(pathItemServers || template.servers || [])
299+
300+
// Prepend base path to the path
301+
const fullPath = basePath ? `/${trimSlashes(basePath)}/${trimSlashes(pathKey)}`.replace(/\/+/g, '/') : pathKey
302+
303+
// Remove servers from path item copy
304+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
305+
const { servers: pathServers, ...pathItemWithoutServers } = pathItem as OpenAPIV3.PathItemObject
306+
307+
return [fullPath, pathItemWithoutServers] as const
308+
})
309+
.filter(([key]) => removeFirstSlash(key as string).startsWith(`${groupWithoutEdgeSlashes}/`)) // note that 'api/v10' is a substring of 'api/v1000'
295310
// remove prefix group for correct path mapping in apiDiff
296-
// todo support the most common case when a group is in servers instead of hardcoded in path, add a test
297-
.map(([key, value]) => [removeFirstSlash(key).substring(groupWithoutEdgeSlashes.length), value]),
311+
.map(([key, value]) => [removeFirstSlash(key as string).substring(groupWithoutEdgeSlashes.length), value]),
298312
),
299313
},
300314
...rest,

test/prefix-groups.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ describe('Prefix Groups test', () => {
162162
}))
163163
})
164164

165-
// todo: case that we don't support due to shifting to the new changelog calculation approach which involves comparison of the entire docs instead of the operation vs operation comparison
166-
test.skip('should compare prefix groups /api/{group} when prefix is overridden in path', async () => {
165+
test('should compare prefix groups /api/{group} when prefix is overridden in path', async () => {
167166
const result = await buildPrefixGroupChangelogPackage({
168167
packageId: 'prefix-groups/mixed-cases-with-path-prefix-override',
169168
config: { files: [{ fileId: 'spec1.yaml' }, { fileId: 'spec2.yaml' }] },
@@ -172,12 +171,12 @@ describe('Prefix Groups test', () => {
172171
expect(result).toEqual(changesSummaryMatcher({
173172
[BREAKING_CHANGE_TYPE]: 1,
174173
[NON_BREAKING_CHANGE_TYPE]: 1,
175-
[ANNOTATION_CHANGE_TYPE]: 1,// todo
174+
[ANNOTATION_CHANGE_TYPE]: 1,
176175
}))
177176
expect(result).toEqual(numberOfImpactedOperationsMatcher({
178177
[BREAKING_CHANGE_TYPE]: 1,
179178
[NON_BREAKING_CHANGE_TYPE]: 1,
180-
[ANNOTATION_CHANGE_TYPE]: 1,// todo
179+
[ANNOTATION_CHANGE_TYPE]: 1,
181180
}))
182181
})
183182

0 commit comments

Comments
 (0)