Skip to content

Commit

Permalink
fix: openapi specs dereferencing and files not found
Browse files Browse the repository at this point in the history
  • Loading branch information
NickHeap2 committed Dec 30, 2021
1 parent 82c1b26 commit 508120b
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 43 deletions.
9 changes: 9 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,16 @@ const OpenAPICoverage = function (emitter, reporterOptions, collectionRunOptions
process.exit(1)
}

if (!utils.specExists(openapiFilename)) {
console.error(`OpenAPI spec ${openapiFilename} does not exist!`)
process.exit(1)
}

utils.initialise(openapiFilename)
if (!utils.getSchema()) {
console.error(`ERROR: Openapi spec ${openapiFilename} could not be parsed!`)
process.exit(1)
}
})

emitter.on('request', function (err, o) {
Expand Down
108 changes: 68 additions & 40 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,84 @@ const deasync = require('deasync')
const fs = require('fs')
const refParser = require('@apidevtools/json-schema-ref-parser')

function dereference (specFilename) {
// use deasync to make this synchronous
let parsed = false
refParser.parse(specFilename, (err, schema) => {
if (err) {
console.error(err)
} else {
// `schema` is just a normal JavaScript object that contains your entire JSON Schema,
// including referenced files, combined into a single object
this.openAPIDocument = schema
async function dereference (specFilename) {
if (!isJestRunning()) {
// use deasync to make this synchronous
let complete = false
refParser.dereference(specFilename, (err, schema) => {
if (err) {
console.error(`ERROR in RefParser: ${err.message ? err.message : err}`)
} else {
this.openAPIDocument = schema
console.log(`Parsed schema file ${specFilename}`)
}
complete = true
})
deasync.loopWhile(() => {
return !complete
})
} else {
try {
this.openAPIDocument = await refParser.dereference(specFilename)
console.log(`Parsed schema file ${specFilename}`)
} catch (err) {
console.error(err)
}
}
}

this.openAPIDocument.callCount = 0
this.openAPIDocument.totalCalls = 0

for (const path in this.openAPIDocument.paths) {
const pathValue = this.openAPIDocument.paths[path]
pathValue.callCount = 0
pathValue.totalCalls = 0

for (const method in pathValue) {
const methodValue = pathValue[method]
methodValue.callCount = 0
methodValue.totalCalls = 0

for (const response in methodValue.responses) {
const responseValue = methodValue.responses[response]
responseValue.callCount = 0
pathValue.totalCalls += 1
methodValue.totalCalls += 1
this.openAPIDocument.totalCalls += 1
}
}
function addCallCounts (spec) {
spec.callCount = 0
spec.totalCalls = 0

for (const path in spec.paths) {
const pathValue = spec.paths[path]
pathValue.callCount = 0
pathValue.totalCalls = 0

for (const method in pathValue) {
const methodValue = pathValue[method]
methodValue.callCount = 0
methodValue.totalCalls = 0

for (const response in methodValue.responses) {
const responseValue = methodValue.responses[response]
responseValue.callCount = 0
pathValue.totalCalls += 1
methodValue.totalCalls += 1
spec.totalCalls += 1
}
}
parsed = true
})
deasync.loopWhile(() => {
return !parsed
})
}
}

function isJestRunning () {
return process.env.JEST_WORKER_ID !== undefined
}

function setSchema (schema) {
this.openAPIDocument = schema
}

function initialise (specFilename) {
if (!fs.existsSync(specFilename) || !fs.lstatSync(specFilename).isFile()) {
console.error(`OpenAPI spec ${specFilename} does not exist!`)
function getSchema () {
return this.openAPIDocument
}

function specExists (specFilename) {
return fs.existsSync(specFilename) && fs.lstatSync(specFilename).isFile()
}

async function initialise (specFilename) {
if (!isJestRunning()) {
this.dereference(specFilename)
} else {
await this.dereference(specFilename)
}
if (!this.openAPIDocument) {
return
}

this.dereference(specFilename)
addCallCounts(this.openAPIDocument)
}

function percentage (calls, totalCalls) {
Expand Down Expand Up @@ -285,4 +311,6 @@ module.exports.updateOperation = updateOperation
module.exports.logError = logError
module.exports.createCoverage = createCoverage
module.exports.setSchema = setSchema
module.exports.getSchema = getSchema
module.exports.dereference = dereference
module.exports.specExists = specExists
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "newman-reporter-openapi",
"version": "0.0.5",
"version": "0.0.6",
"description": "Newman reporter for OpenAPI coverage",
"repository": {
"type": "git",
Expand All @@ -23,7 +23,7 @@
"lint": "standard \"**/*.js\"",
"test": "jest",
"pack": "npm pack",
"install:local": "npm pack && npm i -g newman-reporter-openapi-0.0.1.tgz"
"install:local": "npm pack && npm i -g newman-reporter-openapi-0.0.6.tgz"
},
"files": [
"lib/**"
Expand Down
15 changes: 15 additions & 0 deletions tests/invalid-schema.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
openapi: 3.0.0
info:
title: "Refpath spec"
description: "Refpath spec"
version: 0.0.1
contact:
email: "me@mail.com"
servers:
- url: "/api"
tags:
- name: refpath
paths:
/refpath:
$ref: "missing-refpath.yaml"
6 changes: 6 additions & 0 deletions tests/refpath.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
get:
tags:
- refpath
summary: Get a refpath
description: Get a refpath
operationId: getRefpath
41 changes: 41 additions & 0 deletions tests/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@
/* globals describe it expect */
const utils = require('../lib/utils')

describe('utils dereference', function () {
beforeEach(() => {
utils.setSchema(undefined)
})

it('should load a valid spec and resolve it', async function () {
await utils.dereference('tests/valid-schema.yaml')
const schema = utils.getSchema()
expect(schema).toBeDefined()

expect(schema).toHaveProperty(['paths', '/refpath', 'get', 'summary'])
expect(schema.paths['/refpath'].get.summary).toEqual('Get a refpath')
expect(schema).not.toHaveProperty('callCount')

// console.log(JSON.stringify(schema, null, 2))
})
it('should not dereference an invalid spec', async function () {
await utils.dereference('tests/invalid-schema.yaml')
const schema = utils.getSchema()
expect(schema).not.toBeDefined()
})
})
describe('utils initialise', function () {
beforeEach(() => {
utils.setSchema(undefined)
})

it('should initialise a valid spec', async function () {
await utils.initialise('tests/valid-schema.yaml')
const schema = utils.getSchema()
expect(schema).toBeDefined()

expect(schema).toHaveProperty(['paths', '/refpath', 'get', 'summary'])
expect(schema.paths['/refpath'].get.summary).toEqual('Get a refpath')
expect(schema).toHaveProperty('callCount')
expect(schema.callCount).toEqual(0)

// console.log(JSON.stringify(schema, null, 2))
})
})

describe('utils path', function () {
it('should match a path', function () {
const result = utils.checkPath('/test/path', '/test/path')
Expand Down
15 changes: 15 additions & 0 deletions tests/valid-schema.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
openapi: 3.0.0
info:
title: "Refpath spec"
description: "Refpath spec"
version: 0.0.1
contact:
email: "me@mail.com"
servers:
- url: "/api"
tags:
- name: refpath
paths:
/refpath:
$ref: "refpath.yaml"

0 comments on commit 508120b

Please sign in to comment.