Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* test: Add Failing Test Case for Issue 535. Add failing test case for #535. The problem manifests itself when calling `middleware()` with an object multiple times, as the object itself is mutated which might cause errors on subsequent calls. In this specific example, the parameters for GET /ping/{value} are modified in such a way that a second call will cause a validation error. This happens in `preprocessPathLevelParameters`. * fix: Clone API Spec to avoid Mutation of Parameter Clone the API specification passed to the `middleware()` function. This avoids mutating the `apiSpec` parameter passed to that function, which can lead to unexpected behaviour. Fixes #535.
- Loading branch information
Showing
2 changed files
with
69 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import * as express from 'express'; | ||
import { Server } from 'http'; | ||
import * as request from 'supertest'; | ||
import * as OpenApiValidator from '../src'; | ||
import { OpenAPIV3 } from '../src/framework/types'; | ||
import { startServer } from './common/app.common'; | ||
import { deepStrictEqual } from 'assert'; | ||
|
||
describe('#535 - calling `middleware()` multiple times', () => { | ||
it('does not mutate the API specification', async () => { | ||
const apiSpec = createApiSpec(); | ||
|
||
const app = await createApp(apiSpec); | ||
await request(app).get('/ping/GNU Sir Terry').expect(200, 'GNU Sir Terry'); | ||
app.server.close(); | ||
|
||
deepStrictEqual(apiSpec, createApiSpec()); | ||
}); | ||
}); | ||
|
||
async function createApp( | ||
apiSpec: OpenAPIV3.Document, | ||
): Promise<express.Express & { server?: Server }> { | ||
const app = express(); | ||
|
||
app.use( | ||
OpenApiValidator.middleware({ | ||
apiSpec, | ||
validateRequests: true, | ||
}), | ||
); | ||
app.use( | ||
express.Router().get('/ping/:value', (req, res) => { | ||
res.status(200).send(req.params.value); | ||
}), | ||
); | ||
|
||
await startServer(app, 3001); | ||
return app; | ||
} | ||
|
||
function createApiSpec(): OpenAPIV3.Document { | ||
return { | ||
openapi: '3.0.3', | ||
info: { | ||
title: 'Ping API', | ||
version: '1.0.0', | ||
}, | ||
paths: { | ||
'/ping/{value}': { | ||
parameters: [ | ||
{ | ||
in: 'path', | ||
name: 'value', | ||
required: true, | ||
schema: { type: 'string' }, | ||
}, | ||
], | ||
get: { | ||
responses: { | ||
'200': { description: 'pong!' }, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
} |