Skip to content
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
8 changes: 7 additions & 1 deletion functions/completedSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @param {Options} opts String requirements given by the linter ruleset
*/
export default function (targetVal) {
if (typeof targetVal !== 'object') {
if (targetVal == null || typeof targetVal !== 'object') {
return;
}

Expand All @@ -41,6 +41,12 @@ export default function (targetVal) {
return;
}

// An object with additionalProperties: false and no properties is a valid
// schema representing an intentionally empty object (e.g., {})
if (targetVal.additionalProperties === false) {
return;
}

return [
{
message: 'properties missing for object schema',
Expand Down
84 changes: 84 additions & 0 deletions functions/completedSchema.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,88 @@ describe('completedSchema', () => {
},
]);
});

describe('additionalProperties: false (Issue #57)', () => {
test('should pass for empty object with additionalProperties: false', () => {
const schema = {
type: 'object',
additionalProperties: false,
};
expect(completedSchema(schema)).toBeUndefined();
});

test('should pass for empty object with additionalProperties: false and description', () => {
const schema = {
type: 'object',
description: 'Response for successful operation',
additionalProperties: false,
};
expect(completedSchema(schema)).toBeUndefined();
});

test('should pass for empty object with additionalProperties: false and example', () => {
const schema = {
type: 'object',
example: {},
additionalProperties: false,
};
expect(completedSchema(schema)).toBeUndefined();
});

test('should pass for v1AddOrUpdatePolicyConnectionsResponse pattern', () => {
const schema = {
type: 'object',
example: {},
description: 'Response for a successful association/disassociation of connections to a policy',
additionalProperties: false,
};
expect(completedSchema(schema)).toBeUndefined();
});

test('should fail for empty object without additionalProperties: false', () => {
const schema = {
type: 'object',
};
expect(completedSchema(schema)).toEqual([
{ message: 'properties missing for object schema' },
]);
});

test('should fail for empty object with additionalProperties: true', () => {
const schema = {
type: 'object',
additionalProperties: true,
};
expect(completedSchema(schema)).toEqual([
{ message: 'properties missing for object schema' },
]);
});

test('should fail for empty object with additionalProperties as schema', () => {
const schema = {
type: 'object',
additionalProperties: { type: 'string' },
};
expect(completedSchema(schema)).toEqual([
{ message: 'properties missing for object schema' },
]);
});

test('should pass for object with empty properties and additionalProperties: false', () => {
const schema = {
type: 'object',
properties: {},
additionalProperties: false,
};
expect(completedSchema(schema)).toBeUndefined();
});
});

describe('edge cases', () => {
test('should pass for non-object input', () => {
expect(completedSchema('string')).toBeUndefined();
expect(completedSchema(123)).toBeUndefined();
expect(completedSchema(null)).toBeUndefined();
});
});
});
21 changes: 21 additions & 0 deletions test/resources/general-schema-definition/positive.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@
}
],
"paths": {
"/ack": {
"get": {
"description": "Acknowledge.",
"operationId": "ack",
"tags": ["Sample"],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"description": "Empty success response"
}
}
}
}
}
}
},
"/test": {
"get": {
"description": "Get some test data.",
Expand Down