Skip to content
This repository has been archived by the owner on Nov 8, 2024. It is now read-only.

Validation only content negotiation significant headers for value match #53

Merged
merged 10 commits into from
Mar 12, 2015
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
[![Build Status](https://travis-ci.org/apiaryio/gavel.js.png?branch=master)](https://travis-ci.org/apiaryio/gavel.js)
[![Dependency Status](https://david-dm.org/apiaryio/gavel.js.png)](https://david-dm.org/apiaryio/gavel.js)
[![devDependency Status](https://david-dm.org/apiaryio/gavel.js/dev-status.png)](https://david-dm.org/apiaryio/gavel.js#info=devDependencies)
[![Coverage Status](https://coveralls.io/repos/apiaryio/gavel.js/badge.png?branch=coverage)](https://coveralls.io/r/apiaryio/gavel.js?branch=coverage)
[![Coverage Status](https://coveralls.io/repos/apiaryio/gavel.js/badge.png)](https://coveralls.io/r/apiaryio/gavel.js)


![Gavel logo](https://raw.github.com/apiaryio/gavel/master/img/gavel.png)


## Usage

```
Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,30 @@
"dependencies": {
"amanda": "^0.5.1",
"async": "~0.9.0",
"clone": "~0.1.17",
"commander": "~2.3.0",
"clone": "^1.0.0",
"commander": "^2.6.0",
"curl-trace-parser": "0.0.8",
"googlediff": "0.1.0",
"http-string-parser": "0.0.4",
"json-pointer": "~0.2.2",
"json-pointer": "^0.3.0",
"jsonlint": "~1.6.0",
"media-typer": "~0.3.0",
"tv4": "~1.1.4",
"update": "~0.1.0"
"update": "^0.2.0"
},
"devDependencies": {
"chai": "~1.9.0",
"coffee-script": "~1.8.0",
"mocha": "~1.21.4",
"cucumber": "~0.4.0",
"lodash": "~2.4.1",
"prettyjson": "~1.0.0",
"chai": "^2.1.0",
"codo": "~2.0.6",
"sinon": "~1.10.2",
"coffee-coverage": "~0.4.2",
"jscoverage": "~0.5.4",
"coffee-script": "^1.9.1",
"coveralls": "~2.11.2",
"mocha-lcov-reporter": "0.0.1"
"cucumber": "~0.4.0",
"jscoverage": "~0.5.4",
"lodash": "^3.3.0",
"mocha": "^2.1.0",
"mocha-lcov-reporter": "0.0.1",
"prettyjson": "^1.1.0",
"sinon": "^1.12.2"
},
"scripts": {
"test": "scripts/test",
Expand Down
2 changes: 1 addition & 1 deletion src/mixins/validatable-http-message.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Validatable
@lowercaseHeaders()

@validateHeaders() unless @headers == undefined || @expected.headers == undefined
@validateBody() unless @body == undefined || @expected.body == undefined
@validateBody() unless @body == undefined || (@expected.body == undefined && @expected.bodySchema == undefined)
@validateStatusCode() unless @statusCode == undefined
@validation

Expand Down
15 changes: 13 additions & 2 deletions src/utils/schema-v4-generator.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ class SchemaV4Generator
@schema = undefined
@properties = properties || new SchemaV4Properties {}

# for handling strict values array as caseless
if Array.isArray @properties.valuesStrict
lowercased = []
for val in @properties.valuesStrict
lowercased.push val.toLowerCase()
@properties.valuesStrict = lowercased

#generates json schema
#@return [Object] generated json schema
generate: () ->
Expand Down Expand Up @@ -92,10 +99,14 @@ class SchemaV4Generator
else
schemaDict['additionalItems'] = true

if properties.valuesStrict and @isBaseType schemaType
if properties.valuesStrict is true and @isBaseType schemaType
schemaDict['enum'] = [baseObject]

if (properties.typesStrict and @isBaseType schemaType) or not @isBaseType schemaType
else if Array.isArray(properties.valuesStrict) and @isBaseType schemaType
if properties.valuesStrict.indexOf(objectId?.toLowerCase()) > -1
schemaDict['enum'] = [baseObject]

if (properties.typesStrict and @isBaseType schemaType) or (not @isBaseType schemaType) or firstLevel == true
schemaDict["type"] = schemaType

if schemaType is 'object' and Object.keys(baseObject).length > 0
Expand Down
11 changes: 10 additions & 1 deletion src/validators/headers-json-example.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,16 @@ class HeadersJsonExample extends JsonSchema
#@private
getSchema: (data)->
properties = new SchemaV4Properties {}
properties.set keysStrict: false, valuesStrict: true, typesStrict : false
properties.set
keysStrict: false
typesStrict : false
valuesStrict: [
'content-type'
'accept'
'accept-charset'
'accept-encoding'
'accept-language'
]

schemaGenerator = new SchemaV4Generator json: data, properties: properties

Expand Down
6 changes: 0 additions & 6 deletions src/validators/json-example.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,8 @@ class JsonExample extends JsonSchema
outError['data'] = @expected
throw outError

@expected = JSON.parse(@expected)
@schema = @getSchema @expected

try
@real = JSON.parse(real)
catch error
validatorType = 'string'

super @real, @schema

#@private
Expand Down
2 changes: 1 addition & 1 deletion src/validators/json-schema.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class JsonSchema

if typeof @schema == 'string'
try
@schema = JSON.parse(schema)
@schema = JSON.parse(@schema)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

catch error
outError = new errors.SchemaNotJsonParsableError 'JSON validator: schema: ' + error.message
outError['schema'] = @schema
Expand Down
2 changes: 1 addition & 1 deletion test/cucumber/features
16 changes: 7 additions & 9 deletions test/cucumber/step_definitions/validation_errors_thens.coffee
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
validationErrorsThens = () ->
Given = When = Then = @.defineStep

Then /^Gavel will set some error for "([^"]*)"$/, (component, callback) ->

@validate (error, result) =>
Expand All @@ -11,19 +11,17 @@ validationErrorsThens = () ->
componentValidation = result[component]
results = componentValidation['results']
errorsCount = results.length

if not errorsCount > 0
callback.fail "Expected validation errors on '" + component + "', but there are no validation errors."
callback.fail "Expected validation errors on '" + component + "', but there are no validation errors."

callback()

Then /^Gavel will NOT set any errors for "([^"]*)"$/, (component, callback) ->

@validate (error, result) =>
if error
callback.fail "Error during validation: " + error


component = @toCamelCase(component)
componentValidation = result[component]
results = componentValidation['results']
Expand All @@ -39,7 +37,7 @@ validationErrorsThens = () ->


callback()

Then /^Request or Response is NOT valid$/, (callback) ->
@isValid (error, result) =>
if result
Expand All @@ -52,5 +50,5 @@ validationErrorsThens = () ->
callback.fail "Request or Response is NOT valid and should be valid."
callback()


module.exports = validationErrorsThens
48 changes: 25 additions & 23 deletions test/cucumber/step_definitions/validators_steps.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ validatorStepDefs = () ->
When /^you perform a failing validation on any validatable HTTP component$/, (callback) ->
json1 = '{"a": "b"}'
json2 = '{"c": "d"}'

@component = 'body'

@real =
Expand All @@ -29,38 +29,40 @@ validatorStepDefs = () ->
@validate (error, result) =>
callback.fail "Got error during validation:\n" + error if error
@results = JSON.parse JSON.stringify result

@isValid (error, result) ->
callback.fail error if error
@booleanResult = result
callback()

Then /^the validator output for the HTTP component looks like the following JSON:$/, (expectedJson, callback) ->
Then /^the validator output for the HTTP component looks like the following JSON:$/, (expectedJson, callback) ->
expected = JSON.parse expectedJson
real = @results[@component]
if not _.isEqual real, expected
callback.fail "Not matched! Expected:" + "\n" + \
return callback.fail "Not matched! Expected:" + "\n" + \
JSON.stringify(expected, null, 2) + "\n" + \
"But got:" + "\n" + \
JSON.stringify(real, null, 2)
callback()

else
return callback()

Then /^validated HTTP component is considered invalid$/, (callback) ->
assert.isFalse @booleanResult
callback()

Then /^the validator output for the HTTP component is valid against "([^"]*)" model JSON schema:$/, (model, schema, callback) ->
tv4.validate @results[@component], JSON.parse(schema), (error) ->
if error
if not Object.keys(error).length == 0
callback.fail "Expected no validation errors on schema but got:\n" +
JSON.stringify(error, null, 2)
callback()
valid = tv4.validate @results[@component], JSON.parse(schema)
if not valid
return callback.fail "Expected no validation errors on schema but got:\n" +
JSON.stringify(tv4.error, null, 2)
else
return callback()

Then /^each result entry under "([^"]*)" key must contain "([^"]*)" key$/, (key1, key2, callback) ->
error = @results[@component]
if error == undefined
callback.fail 'Validation result for "' + \
callback.fail 'Validation result for "' + \
@component + \
'" is undefined. Validations: ' + \
JSON.stringify @results, null, 2
Expand All @@ -71,9 +73,9 @@ validatorStepDefs = () ->

Then /^the output JSON contains key "([^"]*)" with one of the following values:$/, (key, table, callback) ->
error = @results[@component]

validators = [].concat.apply [], table.raw()

assert.include validators, error[key]
callback()

Expand All @@ -86,9 +88,9 @@ validatorStepDefs = () ->
@expected['bodySchema'] = data
else if type == 'application/vnd.apiary.http-headers+json'
@expected[@component] = JSON.parse data
else
else
@expected[@component] = data

@expectedType = type
callback()

Expand All @@ -99,7 +101,7 @@ validatorStepDefs = () ->
@real[@component] = data

@realType = type
callback()
callback()

When /^you perform validation on the HTTP component$/, (callback) ->
@validate (error, result) =>
Expand All @@ -109,21 +111,21 @@ validatorStepDefs = () ->
@results = result
@componentResults = @results[@component]
callback()

Then /^validator "([^"]*)" is used for validation$/, (validator, callback) ->
usedValidator = @componentResults['validator']
if validator != usedValidator
callback.fail "Used validator '" + usedValidator + "'" + \
" instead of '" + validator + "'. Got validation results: " + \
JSON.stringify(@results, null, 2)
callback()

Then /^validation key "([^"]*)" looks like the following "([^"]*)":$/, (key, type, expected, callback) ->
real = @componentResults[key]
if type == "JSON"
expected = JSON.parse expected
else if type == "text"
# FIXME investigate how does cucumber docstrings handle
# FIXME investigate how does cucumber docstrings handle
# newlines and remove trim and remove this hack
expected = expected + "\n"

Expand All @@ -135,9 +137,9 @@ validatorStepDefs = () ->
@inspect(real) + "\n" + \
"End"
else if type == "text"
assert.equal expected, real
assert.equal expected, real
callback()

Then /^each result entry must contain "([^"]*)" key$/, (key, callback) ->
@componentResults['results'].forEach (error) ->
assert.include Object.keys(error), key
Expand Down
Loading