|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +const path = require('path'); |
| 4 | +const {describe, it, expect} = require('@jest/globals'); |
| 5 | +const {openapiSort, openapiFilter, openapiChangeCase} = require('../openapi-format'); |
| 6 | + |
| 7 | +describe('openapi-format core API', () => { |
| 8 | + it('openapiSort should return original object when sort is disabled', async () => { |
| 9 | + const doc = {openapi: '3.0.0', info: {title: 'API', version: '1.0.0'}, paths: {}}; |
| 10 | + const result = await openapiSort(doc, {sort: false}); |
| 11 | + expect(result).toBe(doc); |
| 12 | + }); |
| 13 | + |
| 14 | + it('openapiFilter should handle x-tagGroups flagValues filtering branch', async () => { |
| 15 | + const doc = { |
| 16 | + openapi: '3.0.0', |
| 17 | + info: {title: 'API', version: '1.0.0'}, |
| 18 | + tags: [{name: 'pets'}], |
| 19 | + 'x-tagGroups': [{name: 'Group1', tags: ['pets']}], |
| 20 | + paths: {} |
| 21 | + }; |
| 22 | + |
| 23 | + const result = await openapiFilter(doc, {filterSet: {flagValues: [{name: 'Group1'}]}}); |
| 24 | + |
| 25 | + expect(result.data['x-tagGroups']).toEqual([]); |
| 26 | + expect(result.data.tags).toEqual([{name: 'pets'}]); |
| 27 | + }); |
| 28 | + |
| 29 | + it('openapiChangeCase should apply summary, description and securitySchemes ref casing', async () => { |
| 30 | + const doc = { |
| 31 | + openapi: '3.0.0', |
| 32 | + info: {title: 'API', version: '1.0.0'}, |
| 33 | + xRef: {$ref: '#/components/securitySchemes/MyAuth'}, |
| 34 | + components: { |
| 35 | + securitySchemes: { |
| 36 | + MyAuth: {type: 'http', scheme: 'bearer'} |
| 37 | + } |
| 38 | + }, |
| 39 | + paths: { |
| 40 | + '/pets': { |
| 41 | + get: { |
| 42 | + summary: 'List Pets', |
| 43 | + description: 'Returns All Pets' |
| 44 | + } |
| 45 | + } |
| 46 | + } |
| 47 | + }; |
| 48 | + |
| 49 | + const result = await openapiChangeCase(doc, { |
| 50 | + casingSet: { |
| 51 | + componentsSecuritySchemes: 'snake_case', |
| 52 | + summary: 'kebab-case', |
| 53 | + description: 'kebab-case' |
| 54 | + } |
| 55 | + }); |
| 56 | + |
| 57 | + expect(result.data.components.securitySchemes).toHaveProperty('my_auth'); |
| 58 | + expect(result.data.xRef.$ref).toBe('#/components/securitySchemes/my_auth'); |
| 59 | + expect(result.data.paths['/pets'].get.summary).toBe('list-pets'); |
| 60 | + expect(result.data.paths['/pets'].get.description).toBe('returns-all-pets'); |
| 61 | + }); |
| 62 | +}); |
| 63 | + |
| 64 | +describe('openapiSplit API', () => { |
| 65 | + it('throws when output is missing', async () => { |
| 66 | + jest.resetModules(); |
| 67 | + const {openapiSplit} = require('../openapi-format'); |
| 68 | + await expect(openapiSplit({}, {})).rejects.toThrow('Output is required'); |
| 69 | + }); |
| 70 | + |
| 71 | + it('calls split writers for components and paths when output is provided', async () => { |
| 72 | + jest.resetModules(); |
| 73 | + jest.doMock('../utils/split', () => ({ |
| 74 | + writePaths: jest.fn().mockResolvedValue(undefined), |
| 75 | + writeComponents: jest.fn().mockResolvedValue(undefined), |
| 76 | + writeSplitOpenAPISpec: jest.fn().mockResolvedValue(undefined) |
| 77 | + })); |
| 78 | + |
| 79 | + const {openapiSplit} = require('../openapi-format'); |
| 80 | + const splitUtils = require('../utils/split'); |
| 81 | + |
| 82 | + const doc = {components: {schemas: {A: {type: 'object'}}}, paths: {'/a': {get: {}}}}; |
| 83 | + const options = {output: '/tmp/out/openapi.yaml'}; |
| 84 | + await openapiSplit(doc, options); |
| 85 | + |
| 86 | + expect(splitUtils.writeComponents).toHaveBeenCalledWith( |
| 87 | + doc.components, |
| 88 | + expect.objectContaining({outputDir: '/tmp/out', extension: 'yaml'}) |
| 89 | + ); |
| 90 | + expect(splitUtils.writePaths).toHaveBeenCalledWith( |
| 91 | + doc.paths, |
| 92 | + expect.objectContaining({outputDir: '/tmp/out', extension: 'yaml'}) |
| 93 | + ); |
| 94 | + expect(splitUtils.writeSplitOpenAPISpec).toHaveBeenCalledWith( |
| 95 | + doc, |
| 96 | + expect.objectContaining({outputDir: '/tmp/out', extension: 'yaml'}) |
| 97 | + ); |
| 98 | + }); |
| 99 | + |
| 100 | + it('writes only main split spec when components and paths are absent', async () => { |
| 101 | + jest.resetModules(); |
| 102 | + jest.doMock('../utils/split', () => ({ |
| 103 | + writePaths: jest.fn().mockResolvedValue(undefined), |
| 104 | + writeComponents: jest.fn().mockResolvedValue(undefined), |
| 105 | + writeSplitOpenAPISpec: jest.fn().mockResolvedValue(undefined) |
| 106 | + })); |
| 107 | + |
| 108 | + const {openapiSplit} = require('../openapi-format'); |
| 109 | + const splitUtils = require('../utils/split'); |
| 110 | + |
| 111 | + const doc = {openapi: '3.0.0', info: {title: 'API', version: '1.0.0'}}; |
| 112 | + const options = {output: 'openapi.json'}; |
| 113 | + await openapiSplit(doc, options); |
| 114 | + |
| 115 | + expect(splitUtils.writeComponents).not.toHaveBeenCalled(); |
| 116 | + expect(splitUtils.writePaths).not.toHaveBeenCalled(); |
| 117 | + expect(splitUtils.writeSplitOpenAPISpec).toHaveBeenCalledWith( |
| 118 | + doc, |
| 119 | + expect.objectContaining({outputDir: '.', extension: 'json'}) |
| 120 | + ); |
| 121 | + }); |
| 122 | +}); |
0 commit comments