Skip to content
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
"update-lock-file": "update-lock-file @netcracker"
},
"dependencies": {
"@netcracker/qubership-apihub-api-unifier": "dev",
"@netcracker/qubership-apihub-api-unifier": "feature-pathItems",
"@netcracker/qubership-apihub-json-crawl": "1.0.4",
"fast-equals": "4.0.3"
},
"devDependencies": {
"@netcracker/qubership-apihub-compatibility-suites": "dev",
"@netcracker/qubership-apihub-compatibility-suites": "feature-pathItems",
"@netcracker/qubership-apihub-graphapi": "1.0.8",
"@netcracker/qubership-apihub-npm-gitflow": "3.1.0",
"@types/jest": "29.5.11",
Expand Down
7 changes: 7 additions & 0 deletions src/openapi/openapi3.rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,13 @@ export const openApi3Rules = (options: OpenApi3RulesOptions): CompareRules => {
...requestSchemaRules,
}),
},
'/pathItems': {
$: [nonBreaking, breaking, breaking],
'/*': {
$: [nonBreaking, breaking, breaking],
'/*': operationRule
},
},
'/securitySchemes': {
$: [breaking, nonBreaking, breaking],
'/*': {
Expand Down
56 changes: 56 additions & 0 deletions test/compatibility-suites/openapi/path-item.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { compareFiles } from '../utils'
import { diffsMatcher } from '../../helper/matchers'
import { breaking, DiffAction, nonBreaking } from '../../../src'

const SUITE_ID = 'path-item'

const PATH_ITEM_PATH = [
'components',
'pathItems',
'UserOps',
]

describe('Openapi3.1 PathItems', () => {

test('Add method in path item', async () => {
const testId = 'add-method-in-path-item'
const result = await compareFiles(SUITE_ID, testId)
expect(result).toEqual(diffsMatcher([
expect.objectContaining({
action: DiffAction.add,
afterDeclarationPaths: [[...PATH_ITEM_PATH, 'post']],
type: nonBreaking,
}),
]))
})

test('Add unused method in path item', async () => {
const testId = 'add-unused-method-in-path-item'
const result = await compareFiles(SUITE_ID, testId)
expect(result).toEqual([])
})

test('Remove method in path item', async () => {
const testId = 'remove-method-in-path-item'
const result = await compareFiles(SUITE_ID, testId)
expect(result).toEqual(diffsMatcher([
expect.objectContaining({
action: DiffAction.remove,
beforeDeclarationPaths: [[...PATH_ITEM_PATH, 'post']],
type: breaking,
}),
]))
})

test('Replace inline path item to ref', async () => {
const testId = 'replace-inline-path-item-to-ref'
const result = await compareFiles(SUITE_ID, testId)
expect(result).toEqual([])
})

test('Replace ref path item to inline', async () => {
const testId = 'replace-ref-path-item-to-inline'
const result = await compareFiles(SUITE_ID, testId)
expect(result).toEqual([])
})
})
216 changes: 216 additions & 0 deletions test/pathItems.rules.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import { apiDiff, ClassifierType, DiffAction } from '../src'
import { diffsMatcher } from './helper/matchers'

const COMPONENTS_RESPONSE_PATH = [
'components',
'pathItems',
'componentsPathItem',
'post',
'responses',
'200',
]

describe('Openapi3.1 Components PathItems Rules', () => {
test('could be a replace annotation', async () => {
const before = {
'openapi': '3.1.0',
'paths': {
'/path1': {
'post': {
'responses': {
'200': {},
},
},
},
},
'components': {
'pathItems': {
'componentsPathItem': {
'post': {
'responses': {
'200': {
'description': 'Pet successfully added',
},
},
},
},
},
},
}

const after = {
'openapi': '3.1.0',
'paths': {
'/path1': {
'post': {
'responses': {
'200': {},
},
},
},
},
'components': {
'pathItems': {
'componentsPathItem': {
'post': {
'responses': {
'200': {
'description': 'new value',
},
},
},
},
},
},
}

const result = apiDiff(before, after)
expect(result.diffs).toEqual(diffsMatcher([
expect.objectContaining({
action: DiffAction.replace,
beforeValue: 'Pet successfully added',
afterValue: 'new value',
beforeDeclarationPaths: [[
...COMPONENTS_RESPONSE_PATH,
'description',
]],
afterDeclarationPaths: [[
...COMPONENTS_RESPONSE_PATH,
'description',
]],
type: ClassifierType.annotation,
}),
]))
})

test('could be a remove annotation', async () => {
const before = {
'openapi': '3.1.0',
'paths': {
'/path1': {
'post': {
'responses': {
'200': {},
},
},
},
},
'components': {
'pathItems': {
'componentsPathItem': {
'post': {
'responses': {
'200': {
'description': 'Pet successfully added',
},
},
},
},
},
},
}

const after = {
'openapi': '3.1.0',
'paths': {
'/path1': {
'post': {
'responses': {
'200': {},
},
},
},
},
'components': {
'pathItems': {
'componentsPathItem': {
'post': {
'responses': {
'200': {
},
},
},
},
},
},
}

const result = apiDiff(before, after)
expect(result.diffs).toEqual(diffsMatcher([
expect.objectContaining({
action: DiffAction.remove,
beforeValue: 'Pet successfully added',
beforeDeclarationPaths: [[
...COMPONENTS_RESPONSE_PATH,
'description',
]],
type: ClassifierType.annotation,
}),
]))
})
test('could be a add annotation', async () => {
const before = {
'openapi': '3.1.0',
'paths': {
'/path1': {
'post': {
'responses': {
'200': {},
},
},
},
},
'components': {
'pathItems': {
'componentsPathItem': {
'post': {
'responses': {
'200': {
},
},
},
},
},
},
}

const after = {
'openapi': '3.1.0',
'paths': {
'/path1': {
'post': {
'responses': {
'200': {},
},
},
},
},
'components': {
'pathItems': {
'componentsPathItem': {
'post': {
'responses': {
'200': {
'description': 'Pet successfully added',
},
},
},
},
},
},
}

const result = apiDiff(before, after)
expect(result.diffs).toEqual(diffsMatcher([
expect.objectContaining({
action: DiffAction.add,
afterValue: 'Pet successfully added',
afterDeclarationPaths: [[
...COMPONENTS_RESPONSE_PATH,
'description',
]],
type: ClassifierType.annotation,
}),
]))
})
})
Loading