Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(oas): allow skipping the Accept header inference #254

Merged
merged 4 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/oas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ console.log(requests);

Notice the `includeVendorExamples` option affects Swagger specifications only.

Some specifications may have configuration for `Accept` header value in request parameters section. The automatically inferred `Accept` header values may be skipped, to skip these inferred values in output use the `oas2har` function as follows:

```js
import schema from './swagger.json' assert { type: 'json' };
import { oas2har } from '@har-sdk/oas';

const requests = await oas2har(schema, { skipAcceptHeaderInference: true });
console.log(requests);
```

## License

Copyright © 2023 [Bright Security](https://brightsec.com/).
Expand Down
4 changes: 4 additions & 0 deletions packages/oas/src/converter/Converter.ts
derevnjuk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { OpenAPI, Request } from '@har-sdk/core';

export interface ConverterOptions {
skipAcceptHeaderInference?: boolean;
}

export interface Converter {
convert(collection: OpenAPI.Document): Promise<Request[]>;
}
16 changes: 11 additions & 5 deletions packages/oas/src/converter/parts/SubConverterFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import { Oas2BodyConverter, Oas3RequestBodyConverter } from './postdata';
import { Oas2QueryStringConverter, Oas3QueryStringConverter } from './query';
import { Sampler } from '../Sampler';
import { Oas2CookiesConverter, Oas3CookiesConverter } from './cookies';
import { ConverterOptions } from '../Converter';
import { OpenAPI, OpenAPIV2, OpenAPIV3 } from '@har-sdk/core';

export class SubConverterFactory {
constructor(private readonly sampler: Sampler) {}
constructor(
private readonly sampler: Sampler,
private readonly options: ConverterOptions
) {}

public createSubConverter(
spec: OpenAPI.Document,
Expand Down Expand Up @@ -63,15 +67,17 @@ export class SubConverterFactory {
spec: OpenAPI.Document,
oas2Ctor: new (
spec: OpenAPIV2.Document,
sampler: Sampler
sampler: Sampler,
options: ConverterOptions
) => SubConverter<unknown>,
oas3Ctor: new (
spec: OpenAPIV3.Document,
sampler: Sampler
sampler: Sampler,
options: ConverterOptions
) => SubConverter<unknown>
) {
return isOASV3(spec)
? new oas3Ctor(spec as OpenAPIV3.Document, this.sampler)
: new oas2Ctor(spec as OpenAPIV2.Document, this.sampler);
? new oas3Ctor(spec as OpenAPIV3.Document, this.sampler, this.options)
: new oas2Ctor(spec as OpenAPIV2.Document, this.sampler, this.options);
}
}
14 changes: 11 additions & 3 deletions packages/oas/src/converter/parts/headers/HeadersConverter.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConverterOptions } from '../../Converter';
import { OperationObject, ParameterObject } from '../../../types';
import {
filterLocationParams,
Expand All @@ -18,7 +19,8 @@ export abstract class HeadersConverter<T extends OpenAPI.Document>

protected constructor(
private readonly spec: T,
private readonly sampler: Sampler
private readonly sampler: Sampler,
private readonly options: ConverterOptions
) {}

protected abstract createContentTypeHeaders(
Expand All @@ -44,9 +46,15 @@ export abstract class HeadersConverter<T extends OpenAPI.Document>
headers.push(...this.createContentTypeHeaders(pathObj));
}

headers.push(...this.createAcceptHeaders(pathObj));
const acceptHeaders = this.createAcceptHeaders(pathObj);

headers.push(...this.parseFromParams(path, method));
const paramsHeaders = this.parseFromParams(path, method);

const addInferred =
!this.options.skipAcceptHeaderInference ||
!paramsHeaders.some((x) => x.name === 'accept');

headers.push(...(addInferred ? acceptHeaders : []), ...paramsHeaders);

return headers;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConverterOptions } from '../../Converter';
import { LocationParam } from '../LocationParam';
import { Oas2ValueSerializer } from '../Oas2ValueSerializer';
import { Sampler } from '../../Sampler';
Expand All @@ -9,8 +10,12 @@ export class Oas2HeadersConverter extends HeadersConverter<OpenAPIV2.Document> {
private readonly oas2ValueSerializer = new Oas2ValueSerializer();
private readonly oas2MediaTypeResolver: Oas2MediaTypesResolver;

constructor(spec: OpenAPIV2.Document, sampler: Sampler) {
super(spec, sampler);
constructor(
spec: OpenAPIV2.Document,
sampler: Sampler,
options: ConverterOptions
) {
super(spec, sampler, options);
this.oas2MediaTypeResolver = new Oas2MediaTypesResolver(spec);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConverterOptions } from '../../Converter';
import { isObject } from '../../../utils';
import { LocationParam } from '../LocationParam';
import { Sampler } from '../../Sampler';
Expand All @@ -8,8 +9,12 @@ import { Header, OpenAPIV3 } from '@har-sdk/core';
export class Oas3HeadersConverter extends HeadersConverter<OpenAPIV3.Document> {
private readonly uriTemplator = new UriTemplator();

constructor(spec: OpenAPIV3.Document, sampler: Sampler) {
super(spec, sampler);
constructor(
spec: OpenAPIV3.Document,
sampler: Sampler,
options: ConverterOptions
) {
super(spec, sampler, options);
}

protected createContentTypeHeaders(
Expand Down
7 changes: 5 additions & 2 deletions packages/oas/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ export * from './errors';

export const oas2har = (
collection: OpenAPI.Document,
options: { includeVendorExamples?: boolean } = {}
options: {
includeVendorExamples?: boolean;
skipAcceptHeaderInference?: boolean;
} = {}
): Promise<Request[]> => {
if (!collection) {
throw new TypeError('Please provide a valid OAS specification.');
}

const sampler = new Sampler(options);
const baseUrlParser = new BaseUrlParser(sampler);
const subConverterFactory = new SubConverterFactory(sampler);
const subConverterFactory = new SubConverterFactory(sampler, options);
const subConverterRegistry = new SubConverterRegistry(subConverterFactory);
const securityRequirementsFactory = new SecurityRequirementsFactory(sampler);

Expand Down
16 changes: 16 additions & 0 deletions packages/oas/tests/DefaultConverter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,5 +412,21 @@ describe('DefaultConverter', () => {
// assert
expect(result).toStrictEqual(expectedDoc);
});

it('should skip accept header inference when it comes from parameters', async () => {
// arrange
const { inputDoc, expectedDoc } = await createFixture({
inputFile: `./fixtures/params-header.skip-inference.oas.yaml`,
expectedFile: `./fixtures/params-header.skip-inference.oas.result.json`
});

// act
const result: Request[] = await oas2har(inputDoc as any, {
skipAcceptHeaderInference: true
});

// assert
expect(result).toStrictEqual(expectedDoc);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"bodySize": 0,
"cookies": [],
"headers": [
{
"name": "accept",
"value": "application/json;v=1.0"
}
],
"headersSize": 0,
"httpVersion": "HTTP/1.1",
"method": "GET",
"queryString": [],
"url": "https://example.com/api/v1/user"
},
{
"bodySize": 0,
"cookies": [],
"headers": [
{
"name": "accept",
"value": "application/json"
}
],
"headersSize": 0,
"httpVersion": "HTTP/1.1",
"method": "GET",
"queryString": [],
"url": "https://example.com/api/v1/users"
}
]
39 changes: 39 additions & 0 deletions packages/oas/tests/fixtures/params-header.skip-inference.oas.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
openapi: 3.0.3
info:
version: '1.0'
servers:
- url: https://example.com/api/v1
paths:
/user:
get:
parameters:
- name: Accept
in: header
description: ''
schema:
type: string
example: application/json;v=1.0
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/User'
/users:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
components:
schemas:
User:
properties:
id:
type: string
name:
type: string
Loading