Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,37 @@ const parseServerVariableObject = require('./parseServerVariableObject');
const name = 'Server Object';
const requiredKeys = ['url'];

const validateVariablesInURL = (context, object) => {
const url = object.getValue('url');
const variables = object.get('variables');
const parseResult = new context.namespace.elements.ParseResult();

const urlVariables = url
.match(/{(.*?)}/g)
.map(x => x.replace(/[{}]/g, ''));

// if you define a variable that is not in URL it warns (and the variable is ignored).
variables.keys().forEach((key) => {
if (!urlVariables.includes(key)) {
parseResult.push(createWarning(context.namespace,
`Server variable '${key}' is not present in the URL and will be ignored`, variables));

variables.remove(key);
}
});

// if you place a variable in the URL and its not in variables you get a warning that the variable is missing.
urlVariables.forEach((key) => {
if (!variables.hasKey(key)) {
parseResult.push(createWarning(context.namespace,
`URL variable '${key}' is missing within the server variables`, object.get('url')));
}
});

parseResult.push(object);
return parseResult;
};

const parseMember = context => R.cond([
[hasKey('description'), parseString(context, name, false)],
[hasKey('url'), parseString(context, name, true)],
Expand All @@ -23,6 +54,8 @@ const parseMember = context => R.cond([
[R.T, createInvalidMemberWarning(context.namespace, name)],
]);

const hasVariables = object => object.hasKey('variables');

/**
* Parse the OpenAPI 'Server Object' (`#/server`)
* @see http://spec.openapis.org/oas/v3.0.3#server-object
Expand All @@ -32,6 +65,7 @@ const parseMember = context => R.cond([
const parseServerObject = context => pipeParseResult(context.namespace,
R.unless(isObject, createWarning(context.namespace, `'${name}' is not an object`)),
parseObject(context, name, parseMember(context), requiredKeys, [], true),
R.when(hasVariables, R.curry(validateVariablesInURL)(context)),
(object) => {
const resource = new context.namespace.elements.Resource();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,87 @@ describe('#parseServerObject', () => {
expect(parseResult).to.contain.warning("'Server Object' 'variables' is not an object");
});

it("warns when a variable in server 'variables' is not defined in the URL and removes it", () => {
const server = new namespace.elements.Object({
url: 'https://{username}.gigantic-server.com/{version}/',
variables: {
username: {
default: 'Mario',
description: 'API user name',
},
version: {
default: '1.0',
},
location: {
default: 'Prague',
},
},
});

const parseResult = parse(context)(server);
expect(parseResult.length).to.equal(2);
expect(parseResult).to.contain.annotations;
expect(parseResult).to.contain.warning("Server variable 'location' is not present in the URL and will be ignored");

const resource = parseResult.get(0);
expect(resource).to.be.instanceof(namespace.elements.Resource);

const { hrefVariables } = resource;
const firstHrefVariable = hrefVariables.content.content[0];
const secondHrefVariable = hrefVariables.content.content[1];

expect(hrefVariables).to.be.instanceof(namespace.elements.HrefVariables);
expect(hrefVariables.length).to.equal(2);

expect(firstHrefVariable).to.be.instanceof(namespace.elements.Member);
expect(firstHrefVariable.key.toValue()).to.equal('username');
expect(firstHrefVariable.value.default).to.equal('Mario');
expect(firstHrefVariable.value.description.toValue()).to.equal('API user name');

expect(secondHrefVariable).to.be.instanceof(namespace.elements.Member);
expect(secondHrefVariable.key.toValue()).to.equal('version');
expect(secondHrefVariable.value.default).to.equal('1.0');
});

it("warns when a URL defined variable is missing from 'variables'", () => {
const server = new namespace.elements.Object({
url: 'https://{username}.{server}/{version}/',
variables: {
username: {
default: 'Mario',
description: 'API user name',
},
version: {
default: '1.0',
},
},
});

const parseResult = parse(context)(server);
expect(parseResult.length).to.equal(2);
expect(parseResult).to.contain.annotations;
expect(parseResult).to.contain.warning("URL variable 'server' is missing within the server variables");

const resource = parseResult.get(0);
expect(resource).to.be.instanceof(namespace.elements.Resource);

const { hrefVariables } = resource;
const firstHrefVariable = hrefVariables.content.content[0];
const secondHrefVariable = hrefVariables.content.content[1];

expect(hrefVariables).to.be.instanceof(namespace.elements.HrefVariables);
expect(hrefVariables.length).to.equal(2);

expect(firstHrefVariable).to.be.instanceof(namespace.elements.Member);
expect(firstHrefVariable.key.toValue()).to.equal('username');
expect(firstHrefVariable.value.default).to.equal('Mario');
expect(firstHrefVariable.value.description.toValue()).to.equal('API user name');

expect(secondHrefVariable).to.be.instanceof(namespace.elements.Member);
expect(secondHrefVariable.key.toValue()).to.equal('version');
expect(secondHrefVariable.value.default).to.equal('1.0');
});

it('parse server object with variables', () => {
const server = new namespace.elements.Object({
url: 'https://{username}.gigantic-server.com/{version}',
Expand Down