Giter Site home page Giter Site logo

json-validator's Introduction

NAME

JSON::Validator - Validate data against a JSON schema

SYNOPSIS

Using a schema object

JSON::Validator::Schema or any of the sub classes can be used instead of JSON::Validator. The only reason to use JSON::Validator directly is if you don't know the schema version up front.

Basics

use JSON::Validator;
my $jv = JSON::Validator->new;

# Define a schema - http://json-schema.org/learn/miscellaneous-examples.html
# You can also load schema from disk or web
$jv->schema({
  type       => "object",
  required   => ["firstName", "lastName"],
  properties => {
    firstName => {type => "string"},
    lastName  => {type => "string"},
    age       => {type => "integer", minimum => 0, description => "Age in years"}
  }
});

# Validate your data
my @errors = $jv->validate({firstName => "Jan Henning", lastName => "Thorsen", age => -42});

# Do something if any errors was found
die "@errors" if @errors;

Using joi

# Use joi() to build the schema
use JSON::Validator::Joi 'joi';

$jv->schema(joi->object->props({
  firstName => joi->string->required,
  lastName  => joi->string->required,
  age       => joi->integer->min(0),
}));

# joi() can also validate directly
my @errors = joi(
  {firstName => "Jan Henning", lastName => "Thorsen", age => -42},
  joi->object->props({
    firstName => joi->string->required,
    lastName  => joi->string->required,
    age       => joi->integer->min(0),
  }),
);

DESCRIPTION

JSON::Validator is a data structure validation library based around JSON Schema. This module can be used directly with a JSON schema or you can use the elegant DSL schema-builder JSON::Validator::Joi to define the schema programmatically.

Supported schema formats

JSON::Validator can load JSON schemas in multiple formats: Plain perl data structured (as shown in "SYNOPSIS"), JSON or YAML. The JSON parsing is done with Mojo::JSON, while YAML files requires YAML::PP or YAML::XS.

Resources

Here are some resources that are related to JSON schemas and validation:

Bundled specifications

This module comes with some JSON specifications bundled, so your application don't have to fetch those from the web. These specifications should be up to date, but please submit an issue if they are not.

Files referenced to an URL will automatically be cached if the first element in "cache_paths" is a writable directory. Note that the cache headers for the remote assets are not honored, so you will manually need to remove any cached file, should you need to refresh them.

To download and cache an online asset, do this:

JSON_VALIDATOR_CACHE_PATH=/some/writable/directory perl myapp.pl

Here is the list of the bundled specifications:

Optional modules

ATTRIBUTES

cache_paths

Proxy attribute for "cache_paths" in JSON::Validator::Store.

formats

This attribute will be used as default value for "formats" in JSON::Validator::Schema. It is highly recommended to change this directly on the "schema" instead:

$jv->formats(...);         # Legacy
$jv->schema->formats(...); # Recommended way

recursive_data_protection

This attribute will be used as default value for "recursive_data_protection" in JSON::Validator::Schema. It is highly recommended to change this directly on the "schema" instead:

$jv->recursive_data_protection(...);         # Legacy
$jv->schema->recursive_data_protection(...); # Recommended way

store

$store = $jv->store;

Holds a JSON::Validator::Store object that caches the retrieved schemas. This object will be shared amongst different "schema" objects to prevent a schema from having to be downloaded again.

ua

Proxy attribute for "ua" in JSON::Validator::Store.

METHODS

bundle

This method can be used to get a bundled version of "schema". It will however return a data-structure instead of a new object. See "bundle" in JSON::Validator::Schema for an alternative.

# These two lines does the same
$data = $jv->bundle;
$data = $jv->schema->bundle->data;

# Recommended way
$schema = $jv->schema->bundle;

coerce

This attribute will be used as default value for "coerce" in JSON::Validator::Schema. It is highly recommended to change this directly on the "schema" instead:

$jv->coerce(...);         # Legacy
$jv->schema->coerce(...); # Recommended way

get

Proxy method for "get" in JSON::Validator::Schema.

new

$jv = JSON::Validator->new(%attributes);
$jv = JSON::Validator->new(\%attributes);

Creates a new JSON::Validate object.

load_and_validate_schema

This method will be deprecated in the future. See "errors" in JSON::Validator::Schema and "is_invalid" in JSON::Validator::Schema instead.

schema

$jv     = $jv->schema($json_or_yaml_string);
$jv     = $jv->schema($url);
$jv     = $jv->schema(\%schema);
$jv     = $jv->schema(JSON::Validator::Joi->new);
$jv     = $jv->schema(JSON::Validator::Schema->new);
$schema = $jv->schema;

Used to set a schema from either a data structure or a URL.

$schema will be an instance of JSON::Validator::Schema::Draft4, JSON::Validator::Schema::Draft6 JSON::Validator::Schema::Draft7, JSON::Validator::Schema::Draft201909, JSON::Validator::Schema::OpenAPIv2, JSON::Validator::Schema::OpenAPIv3 or JSON::Validator::Schema.

The $url can take many forms, but needs to point to a text file in the JSON or YAML format.

  • file://...

    A file on disk. Note that it is required to use the "file" scheme if you want to reference absolute paths on your file system.

  • http://... or https://...

    A web resource will be fetched using the Mojo::UserAgent, stored in "ua".

  • data://Some::Module/spec.json

    Will load a given "spec.json" file from Some::Module using "data_section" in JSON::Validator::Util.

  • data:///spec.json

    A "data" URL without a module name will use the current package and search up the call/inheritance tree.

  • Any other URL

    An URL (without a recognized scheme) will be treated as a path to a file on disk. If the file could not be found on disk and the path starts with "/", then the will be loaded from the app defined in "ua". Something like this:

      $jv->ua->server->app(MyMojoApp->new);
      $jv->ua->get('/any/other/url.json');
    

validate

Proxy method for "validate" in JSON::Validator::Schema.

SEE ALSO

COPYRIGHT AND LICENSE

Copyright (C) 2014-2021, Jan Henning Thorsen

This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.

AUTHORS

Project Founder

Jan Henning Thorsen - [email protected]

Contributors

  • Aleksandr Orlenko
  • Alexander Hartmaier
  • Alexander Karelas
  • Bernhard Graf
  • Brad Barden
  • Dagfinn Ilmari Mannsåker
  • Daniel Böhmer
  • David Cantrell
  • Ed J
  • Ere Maijala
  • Fabrizio Gennari
  • Ilya Rassadin
  • Jason Cooper
  • Karen Etheridge
  • Kenichi Ishigaki
  • Kevin M. Goess
  • Kirill Matusov
  • Krasimir Berov
  • Lari Taskula
  • Lee Johnson
  • Martin Renvoize
  • Mattias Päivärinta
  • Michael Jemmeson
  • Michael Schout
  • Mohammad S Anwar
  • Nick Morrott
  • Pierre-Aymeric Masse
  • Roy Storey
  • Russell Jenkins
  • Sebastian Riedel
  • Stephan Hradek
  • Tim Stallard
  • Zoffix Znet

json-validator's People

Contributors

abraxxa avatar akarelas avatar augensalat avatar charsbar avatar dboehmer avatar drhyde avatar elcamlost avatar eremaijala avatar fabzzap avatar iamb avatar ilmari avatar jhthorsen avatar jlcooper avatar karenetheridge avatar kberov avatar khvzak avatar kiwiroy avatar knowledgejunkie avatar kraih avatar leejo avatar manwar avatar mattias-p avatar melhesedek avatar mjemmeson avatar mohawk2 avatar mrenvoize avatar mschout avatar pamasse avatar skeeve avatar zoffixznet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-validator's Issues

Make boolean coercion work for B::SVp_IOK values

There's a line in _validate_type_boolean

and (B::svref_2object(\$value)->FLAGS & B::SVp_NOK or $value =~ /^(true|false)$/))

so that values that have the flag B::SVp_NOK on are coerced but other values are not. In other parts of the code, B::svref_2object(\$value)->FLAGS & (B::SVp_IOK | B::SVp_NOK) is checked instead, and this makes more sense. Now, with coerce on, 0.5 is considered a valid boolean value but 2 is not, for example.

Why not change _validate_type_boolean so it checks B::SVp_IOK | B::SVp_NOK?

Possible hash randomization problem in test suite

With JSON-Validator-2.04 I see the following test failure, randomly, only for perls >= 5.18 (so it's possible a problem with hash randomization):

#   Failed test 'get /undef/undef/y'
#   at t/get.t line 12.
#     Structures begin differing at:
#          $got->[0][0] = 'foo'
#     $expected->[0][0] = 'first'

#   Failed test 'get /undef/undef/y flatten'
#   at t/get.t line 14.
#     Structures begin differing at:
#          $got->[0] = 'foo'
#     $expected->[0] = 'first'
# Looks like you failed 2 tests of 6.
t/get.t ................................ 
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/6 subtests 

Test failures

t/swagger-validate-response-object.t .. Could not load document from data://main/spec.json#:
    Missing or empty input at /perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Swagger2.pm line 386.

Installed is Swagger2 0.27

Actually I wanted to upgrade Swagger2, but Swagger2 needs JSON::Validator, and
JSON::Validator needs Swagger2 to test.

Installing JSON::Validator with --notest, then installing Swagger2, and then
running the above test again, it succeeds.
So I guess you should check for a min version of Swagger2 there.

Array allowed as property value?

Great module, thanks. Just what I needed and working great.

One small thing I noticed, which may or may not be an issue. I had a schema with an object on it, and accidently put the required field in properties. Something like:

"type": "object",
"properties": {
    "required": [ "test" ],

And the strange thing is this does not cause an error? An array is not a valid value for a property definition, is it?

Hope this is useful, thanks again for the great software.

Possible issue with minProperties

Hi,

I'm having trouble getting minProperties to be enforced:

#!/usr/bin/env perl
use strict;
use warnings;
use JSON::Validator;

my $validator = JSON::Validator->new;
$validator->schema({
  foo => {
    type => 'object',
    properties => {
      bar => {
        type => 'integer',
      }
    },
    minProperties => 1,
  }
});

print $validator->validate({ foo => { } });

I'm running version 0.86 on Perl 5.22.0.

With YAML::Syck, `additionalProperties: false` is treated as true

When using YAML::Syck, the validator does not complain about
additional properties, despite additionalProperties: false

use JSON::Validator;
my $validator = JSON::Validator->new;

my $schema_file = $ARGV[0] || "/path/to/schema.yaml";
$validator->schema($schema_file);

my @errors = $validator->validate(
    {
        firstName => "Jan Henning",
        lastName => "Thorsen",
        age => 42,
    },
);
# YAML::XS: like expected: "/: Properties not allowed: age."
# YAML::Syck: no errors
say for @errors;

schema.yaml:

---
type: object
required: [firstName, lastName]
additionalProperties: false
properties:
    firstName: { type: string }
    lastName: { type: string }

https://github.com/jhthorsen/json-validator/blob/master/lib/JSON/Validator.pm#L548
here $additional has the value false as a string.

Same file loaded multiple times

Commit 12808e9 replaces Cwd::abs_path() with Mojo::File->to_abs(). After mojolicious/mojo#1030, Mojo::File->to_abs has been using File::Spec's rel2abs. rel2abs documentation mentions:

If $path is absolute, it is cleaned up and returned using "canonpath".

Then, canonpath has the following documentation

Note that this does not collapse x/../y sections into y. This is by design. If /foo on your system is a symlink to /bar/baz, then /foo/../quux is actually /bar/quux, not /quux as a naive ../-removal would give you. If you want to do this kind of processing, you probably want Cwd's realpath() function to actually traverse the filesystem cleaning up paths like this.

Cwd::realpath() is a synonym for Cwd::abs_path(). This means that since 12808e9, we are no longer cleaning up the paths the same way as with Cwd::abs_path(). In certain circumstances, this will cause the same file to be loaded multiple times because the path is represented in different ways.

For example in my spec I now see the same file being loaded twice:

[JSON::Validator] Loading schema /home/ubuntu/json-validator/t/spec/koha-swagger/definitions.json namespace=/home/ubuntu/json-validator/t/spec/koha-swagger/definitions.json scheme=file
[JSON::Validator] Loading schema /home/ubuntu/json-validator/t/spec/koha-swagger/paths/../definitions.json namespace=/home/ubuntu/json-validator/t/spec/koha-swagger/paths/../definitions.json scheme=file

(...and the same is happening for multiple different files)

When I replace Mojo::File->to_abs back to Cwd::abs_path at 12808e9#diff-adc6881507836d26fecdde466d40eea1L132, the same files are no longer loaded multiple times and it shows as a nice performance improvement (about half a second for our relatively large spec).

Would it be reasonable to switch back to Cwd::abs_path() or perhaps come up with another solution to avoid loading the same file multiple times?

Thanks!

It was possible to refer to files on disk before

When the functionality was in Swagger2::SchemaValidator I was able to refer from one schema file to places in other files. Now the whole reference is considered as file name and not as it was before (filename.ext#/path/subpath).
Example:
Having the file /home/berov/opt/private_dev/api/lib/API/etc/APIs/users.yaml I was refering in it to a "definitions" file and an exact place in it: "lib/API/etc/APIs/definitions.yaml#/definitions/Users".
users.yaml

      responses:
        200:
          description: A paged array of users
          schema: {$ref: "lib/API/etc/APIs/definitions.yaml#/definitions/Users"}

definitions.yaml:

---
definitions:
  User:
    required:
      - id
      - group_id
      - login_name
    properties:
      id:
        type: integer
      group_id:
        type: integer
      login_name:
        type: string
  Users:
    type: array
    items:
      $ref: User

Now I see the following error (JSON_VALIDATOR_DEBUG=1):

Server available at http://[::]:5000
This module is replaced by JSON::Validator. at /home/berov/opt/public_dev/swagger2/lib/Swagger2/SchemaValidator.pm line 17, <DATA> line 2231.
[JSON::Validator] Loading schema from /home/berov/opt/private_dev/api/lib/API/etc/APIs/users.yaml (/home/berov/opt/private_dev/api/lib/API/etc/APIs/users.yaml)
[JSON::Validator] Register /home/berov/opt/private_dev/api/lib/API/etc/APIs/users.yaml
[JSON::Validator] Register /home/berov/opt/private_dev/api/lib/API/etc/APIs/users.yaml
[JSON::Validator] Resolve lib/API/etc/APIs/definitions.yaml#/definitions/Error
[JSON::Validator] Loading schema from lib/API/etc/APIs/definitions.yaml#/definitions/Error (lib/API/etc/APIs/definitions.yaml)
Use of uninitialized value $doc in concatenation (.) or string at /home/berov/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/JSON/Validator.pm line 347, <DATA> line 2231.
Can't load application from file "/home/berov/opt/private_dev/api/bin/api": Could not load document from lib/API/etc/APIs/definitions.yaml#/definitions/Error: Can't open file "lib/API/etc/APIs/definitions.yaml#/definitions/Error": No such file or directory at /home/berov/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/JSON/Validator.pm line 341.
 () at /home/berov/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/JSON/Validator.pm line 347, <DATA> line 2231.
Compilation failed in require at (eval 48) line 1, <DATA> line 2231.

Accommodating default values?

I am wondering if there is any possibility of accommodating default values from schemas? It's in the spec, but from what I understand not generally implemented.

Assuming this is not currently implemented, which I don't believe it to be, it would of course mean that the validator would need to modify the data it was validating, to add the default values to it, which would not work in all cases. Validating a string would not make sense for the default values to be added to that string. It only really seems to make sense as an option when validating a data structure. So perhaps it is out of scope for JSON::Validator.

I'm not sure how it could best be implemented, perhaps there could be an option for this. Just putting the idea out there as it's a feature I've found useful in the past with XML Schemas and would be able to make use of from JSON Schemas if the option were available.

Perhaps it would need its own module (JSON::Validator::Bleh?), that would load some JSON, validate it against a schema and return a data structure with default values included where appropriate. If there are any other features of JSON Schema that require augmenting the data, it could be a place for them too.

Integer path param ending with \w warns and passes validation

(Note: I'm using Mojolicious::Plugin::OpenAPI, so it's possibly a bug from there)

I have an integer path parameter: "parameters" : [ { "in": "path", "name": "id", "type": "integer" } ],, and when I give it a value such as "42a" I get an unexpected warning and there is no validation failure.

I logged the value of $value on the lines before and after the line causing the warning and include it in the output below:

perl -Ilocal/lib/perl5 -Ilib script/swagger.pl get /document/42a
"42a" #L79 `p $value;`
Argument "\x{34}\x{32}..." isn't numeric in addition (+) at local/lib/perl5/JSON/Validator/OpenAPI.pm line 80.
42    #L81 `p $value;`

# "\x{34}\x{32}" is 42

Seems like it might be an issue with coercing somewhere, but I couldn't figure out how to golf it

perl -E 'my $x = "42a"; $x += 0; say $x'
42

t/openapi-set-request.t fails

See subject. The test seems only to not fail if Mojolicious::Plugin::OpenAPI is not installed. Otherwise I see failures like:

#   Failed test '200 OK'
#   at t/openapi-set-request.t line 27.
#          got: '500'
#     expected: '200'

#   Failed test 'exact match for JSON Pointer "/bool"'
#   at t/openapi-set-request.t line 27.
#     Structures begin differing at:
#          $got = undef
#     $expected = 0

#   Failed test 'exact match for JSON Pointer "/bool"'
#   at t/openapi-set-request.t line 28.
#     Structures begin differing at:
#          $got = undef
#     $expected = 1

#   Failed test 'exact match for JSON Pointer "/bool"'
#   at t/openapi-set-request.t line 29.
#     Structures begin differing at:
#          $got = undef
#     $expected = 1

#   Failed test 'exact match for JSON Pointer "/this_stack/whatever"'
#   at t/openapi-set-request.t line 31.
#          got: undef
#     expected: 'something'

#   Failed test 'exact match for JSON Pointer "/whatever"'
#   at t/openapi-set-request.t line 31.
#          got: undef
#     expected: 'something'
# Looks like you failed 6 tests of 13.
t/openapi-set-request.t ...............
Dubious, test returned 6 (wstat 1536, 0x600)
Failed 6/13 subtests

enum check is failing for array item property

Schema:

{
   "required" : [
      "update"
   ],
   "type" : "object",
   "properties" : {
      "update" : {
         "maxItems" : 1,
         "type" : "array",
         "minItems" : 1,
         "items" : [
            {
               "enum" : [
                  "haha"
               ],
               "type" : "string"
            }
         ]
      }
   }
}

Input:

{"update": ["hah"]}

Tested against http://www.jsonschemavalidator.net/ and it's throwing errors as expected but the Perl module does not.

Thanks in advance!

Circular dependency

Trying to install JSON::Validator and it cannot as Swagger2 is not available, cannot install Swagger2 as it requires JSON::Validator 😄

Obviously I can cpanm --force to get it through, but that is only a stop gap measure

Nested $ref error

When using nested $refs.. i.e. ref to one file that refs another file I am seeing the following error in the console:

Use of uninitialized value $pointer in substitution (s///) at /home/rebus/.plenv/versions/5.20.2/lib/perl5/site_perl/5.20.2/Mojo/JSON/Pointer.pm line 15, line 2231.

I've written a test that shows this: https://github.com/mrenvoize/json-validator/tree/nested-refs

coerce(1) has no effect on negative and float numbers

$v->coerce(1)->validate({validNumber => "0.1"}) fails with Expected number - got string. at /validNumber with the following schema:

{
  "type": "object",
  "properties": {
    "validNumber": {
      "type": "number"
    }
  }
}

Affects any string with valid JSON number that matches /\D/.

The error spec is cached twice?

We have somehow ended up with the internal error document cached twice in the module.

json-validator/lib/JSON/Validator/cache/49c95b866e40f788892a7fb3c816b0e8
json-validator/lib/JSON/Validator/cache/eaa832720f36cff0abc20c05236a9cd9

$ref support and multi-file specifications

From @mrenvoize on September 16, 2015 16:11

I was hoping to create a structure something along the lines described here

But this seems to be incompatible with the current implementation of the mojo plugin structure.. any thoughts on how to achieve similar with this swagger implementation?

Copied from original issue: jhthorsen/swagger2#33

Cached specifications never expire

Probably makes sense to have some sort of sensible default expiry time on cached specifications, otherwise you have to make sure you clear up cached specifications manually before calling JSON::Validator or risk getting an outdated spec for the given namespace.

Problem validating a schema

Hello,

I still have an error that I'm not able to solve while trying to validate my schema. Probably a newbye error, but after a lot of reading, I'm still uable to understand why it fails:

$ mojo swagger2 validate pb-server/api.yml 
/paths/~1conf~1{confname}/get/parameters/0: oneOf failed: oneOf failed: Missing property. Missing property. Properties not allowed: description, in, name, required.

The YAML file is:

---
swagger: '2.0'
info:
  title: Project-Builder.org
  description: PBSUMMARY
  license:
    name: General Public License 3.0
    url: http://www.gnu.org/
  #termsOfService: 'http://www.example.com/terms'
  contact:
    name: API Support
    url: 'http://www.project-builder.org/support'
    #email: [email protected]
  version: 'PBAPIVER'
host: localhost
basePath: /api/vPBAPIVER
schemes:
  - http
consumes:
  - application/json
  - application/yaml
produces:
  - application/json
  - application/yaml
# Global parameters
paths:
  /doc:
    get:
      summary: API Documentation
      operationId: docPb
      tags:
        - pb
      responses:
        '200':
          description: Expected response to a valid request
          schema:
            $ref: '#/definitions/Conf'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'
  /prj:
    get:
      summary: List all projects
      operationId: listPrj
      tags:
        - prj
      responses:
        '200':
          description: List of all projects managed by project-builder.org
          schema:
            $ref: '#/definitions/Prj'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'
    put:
      summary: Create a new project
      operationId: newPrj
      tags:
        - prj
      parameters:
        - name: name
          in: body
          description: Add project by name
          required: true
          schema:
            $ref: '#/definitions/Prj'
      responses:
        '200':
          description: Expected response to a valid request
          schema:
            $ref: '#/definitions/Prj'
        '409':
          description: Null response
          schema:
            $ref: '#/definitions/Error'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'
  /conf:
    get:
      summary: List all configuration parameters for a specific project
      operationId: listConf
      tags:
        - conf
      parameters:
        - $ref: '#/parameters/prjName'
      responses:
        '200':
          description: Expected response to a valid request
          schema:
            items:
              $ref: '#/definitions/Conf'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'
  '/conf/{confname}':
    get:
      operationId: showConf
      summary: Get a configuration item
      tags:
        - conf
      parameters:
        - name: confname
          in: path
          required: true
          description: The name of the configuration item that will be queried
        - $ref: '#/parameters/prjName'
      responses:
        '200':
          description: Expected response to a valid request
          schema:
            $ref: '#/definitions/Conf'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'
parameters:
  prjName:
    required: true
    name: pbproj
    in: body
    description: The name of the project that will be queried
    schema:
      type: string
      default: 'pb'
definitions:
  Prj:
    required:
      - name
    properties:
      name:
        type: string
      tag:
        type: string
  Conf:
    required:
      - name
    properties:
      name:
        type: string
      tag:
        type: string
  Error:
    required:
      - code
      - message
    properties:
      code:
        type: integer
        format: int32
      message:
        type: string

Thanks in advance for any hint...

"mojo swagger2 validate" and http://editor.swagger.io/# say my spec is invallid but it works

Hi,
I am confused how my tests PASS and how my api specification is wrong.
Attaching all I think is relevant. thanks in advance.

Error: code on http://editor.swagger.io/ : "ONE_OF_MISSING"



Error when validating on the command line:

mojo swagger2 validate example.yaml
/paths/~1/get/responses/200: Expected only one to match.

example.yaml:

---
# Specifiaction for this file format is at http://swagger.io/specification/
swagger: "2.0"
info:
  version: 1.0
  title: Swagger Example
  license:
    name: restricted
  contact: {name: "Chain Solutions"}
host: localhost:5000
basePath: /v1
schemes:
  - http
consumes:
  - application/json
produces:
  - application/json
paths:
  /:
    get:
      x-mojo-controller: "APIComms::Controller::Example"
      summary: Says Hello
      operationId: welcome
      responses:
        200:
          description: Producess a wellcome message
          #Specify the structure of the output strictly
          schema:
            type: object
            title: message
            properties:
              msg:
                type: string
                required: true
                minLength: 51
                maxLength: 51

Content of Example.pm

package APIComms::Controller::Example;
use Mojo::Base 'APIComms::Controller';

# This action will render a template and json
our $MSG = 'Welcome to the Mojolicious real-time web framework!';

sub welcome {
    my ($c, $args, $cb) = @_;

    #handle case when called via API
    if ($cb) {
        return $c->$cb({msg => $MSG}, 200);
    }

    # Render template "example/welcome.html.ep" with message
    $c->render(msg => $MSG);
    return;
}

1;

t/example.t

#!perl
#example.t
use Mojo::Base -strict;
use Test::Mojo;
use Test::More;
use Test::Warnings;
use File::Spec::Functions;
my $t   = Test::Mojo->new('APIComms');
my $app = $t->app;

$t->get_ok('/v1')->status_is(200)->json_has('/msg' => 'Has "msg" property');

#check schema strictness
{
    no warnings 'once';
    local $APIComms::Controller::Example::MSG = 'too short';
    my $m = 'String is too short';
    $t->get_ok('/v1')->status_is(500)->json_like('/errors/0/message' => qr/$m/, $m);
}
{
    no warnings 'once';
    my $m = 'String is too long';
    local $APIComms::Controller::Example::MSG = ('too short' x 10);
    $t->get_ok('/v1')->status_is(500)->json_like('/errors/0/message' => qr/$m/, "$m");
}
done_testing;
berov@u165:~/opt/private_dev/apicomms$ prove -j1 -lrv t/example.t 
t/example.t .. 
ok 1 - GET /v1
ok 2 - 200 OK
ok 3 - Has "msg" property
ok 4 - GET /v1
ok 5 - 500 Internal Server Error
ok 6 - String is too short
ok 7 - GET /v1
ok 8 - 500 Internal Server Error
ok 9 - String is too long
ok 10 - no (unexpected) warnings (via done_testing)
1..10
ok
All tests successful.
Files=1, Tests=10,  1 wallclock secs ( 0.05 usr  0.01 sys +  1.16 cusr  0.07 csys =  1.29 CPU)
Result: PASS

Improve input validation, by also validating double and floats

https://github.com/jhthorsen/json-validator/blob/master/t/openapi-formats.t has some tests marked as TODO. I would like to see if these tests can be improved:

$ prove -vl t/openapi-formats.t
...
ok 7 - valid: {"v":1.10000002384186} # TODO cannot test double, since input is already rounded
...
ok 10 - valid: {"v":-1.10000002384186} # TODO No idea how to test floats
ok 11 - valid: {"v":1.10000002384186} # TODO No idea how to test floats
not ok 12 - errors: /v: Does not match float format. # TODO No idea how to test floats
...
Test Summary Report
-------------------
t/openapi-formats.t (Wstat: 0 Tests: 22 Failed: 0)
  TODO passed:   7, 10-11
Files=1, Tests=22,  0 wallclock secs ( 0.02 usr  0.01 sys +  0.18 cusr  0.01 csys =  0.22 CPU)
Result: PASS

Do any of you know how to fix those tests?

potential bug in anyOf multipleOf

I was testing the module and I came across this potential error. Here's my schema:

{  
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "title": "test",
  "description": "test",
  "properties" : { 
    "name" : { 
      "type": "number",
      "anyOf": [
        {"multipleOf": 5}, 
        {"multipleOf": 3}
      ]   
    } 
  }                                                                                                                                                                           
}

This is my test input:

{"name": 6}

This is supposed to validate fine but I got this error:

{
 'path' => '/name',
 'message' => 'Not multiple of 5.'
}, 'JSON::Validator::Error' )

Would appreciate it if you could verify. Thanks!

use of Mojolicious?

Thanks for this module! It's quite complete.

The only thing I'm worried about, is the fact that it requires the whole Mojolicious stack.
Can one just use LWP::UserAgent and JSON(::XS) instead of Mojo::UserAgent and Mojo::JSON?
I'm sure Mojolicious uses similar packages in the background.

I never used Mojolicious, so I do not know the advantages.

Email format validation is SCARY

Test code:
https://pastebin.com/Ya07Qv9e

Results:

' or email='[email protected]: JSON::Validator | -
a@' or email='a.a: JSON::Validator | -
a@a.' or email='a: JSON::Validator | -
' or email='a@' or email='a.' or email='a: JSON::Validator | -
 @a.a: - | -
[email protected]: JSON::Validator | -
[email protected]: - | -
[email protected]: JSON::Validator | -
[email protected]: - | -
[email protected]: JSON::Validator | -
[email protected].: JSON::Validator | -
[email protected].: JSON::Validator | -
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
email@[123.123.123.123]: JSON::Validator | Email::Valid
"email"@example.com: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
much."more\ unusual"@example.com: JSON::Validator | Email::Valid
very.unusual."@"[email protected]: JSON::Validator | Email::Valid
very."(),:;<>[]".VERY."very@\\\ \"very"[email protected]: JSON::Validator | Email::Valid
plainaddress: - | -
#@%^%#$@#$@#.com: JSON::Validator | -
@example.com: - | -
Joe Smith <[email protected]>: JSON::Validator | Email::Valid
email.example.com: - | -
email@[email protected]: JSON::Validator | -
[email protected]: JSON::Validator | -
[email protected]: - | -
[email protected]: JSON::Validator | -
あいうえお@example.com: - | -
[email protected] (Joe Smith): JSON::Validator | Email::Valid
email@example: JSON::Validator | -
[email protected]: JSON::Validator | -
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | Email::Valid
[email protected]: JSON::Validator | -
[email protected]: JSON::Validator | -
"(),:;<>[\]@example.com: - | -
just"not"[email protected]: JSON::Validator | -
this\ is\"really\"not\\[email protected]: JSON::Validator | -

multipleOf is broken for floats

$v->validate({validNumber => 2.01}) fails with Not multiple of 0.01. at /validNumber with the following schema:

{
  "type": "object",
  "properties": {
    "validNumber": {
      "type": "number",
      "multipleOf": 0.01
    }
  }
}

json reference validation

Hi, can I know if json reference is validated ? Since by running the validator, we realised that it does not complain, even though the reference is non-existent.

https://github.com/opentargets/json_schema/blob/master/src/evidence/literature_mining.json#L27

https://raw.githubusercontent.com/opentargets/json_schema/1.2.5/src/evidence/base.json#base_evidence/definitions/single_lit_reference

"base_evidence" doesn't exisit
https://github.com/opentargets/json_schema/blob/master/src/evidence/base.json#L80
"$ref": "#/definitions/single_lit_reference"

Thanks!
ck

oneOf does not work properly in version 0.96

Hi, by upgrading from version 0.92=>0.97, we hit into the error below, which wasn't happening before:

Validation error on evidence line 639 : $VAR1 = bless( {
'path' => '/',
'message' => 'allOf failed: allOf failed: All of the oneOf rules match.'
}, 'JSON::Validator::Error' );

We think it might be a new bug, this is the schema we use

https://github.com/opentargets/json_schema/blob/master/src/evidence/base.json#L24

and a single line of our json data, thanks.

{"disease": {"name": "breast adenocarcinoma", "source_name": "breast adenocarcinoma", "id": "http://www.ebi.ac.uk/efo/EFO_0000304"}, "sourceID": "eva_somatic", "target": {"activity": "http://identifiers.org/cttv.activity/damaging_to_target", "id": "http://identifiers.org/ensembl/ENSG00000023287", "target_type": "http://identifiers.org/cttv.target/gene_variant"}, "literature": {"references": [{"lit_id": "http://europepmc.org/abstract/MED/12068296"}]}, "evidence": {"urls": [{"nice_name": "Further details in ClinVar database", "url": "http://www.ncbi.nlm.nih.gov/clinvar/RCV000004183"}], "date_asserted": "2016-10-03T00:00:00", "known_mutations": [{"preferred_name": "splice_acceptor_variant", "functional_consequence": "http://purl.obolibrary.org/obo/SO_0001574"}], "evidence_codes": ["http://purl.obolibrary.org/obo/ECO_0000205"], "resource_score": {"type": "probability", "value": 1}, "is_associated": true, "provenance_type": {"database": {"version": "1.0", "dbxref": {"version": "2015-04", "id": "http://identifiers.org/clinvar", "url": "http://identifiers.org/clinvar.record/RCV000004183"}, "id": "EVA"}, "expert": {"statement": "Primary submitter of data", "status": true}, "literature": {"references": [{"lit_id": "http://europepmc.org/abstract/MED/12068296"}]}}}, "unique_association_fields": {"phenotype": "http://www.ebi.ac.uk/efo/EFO_0000304", "clinvarAccession": "RCV000004183", "gene": "ENSG00000023287", "alleleOrigin": "somatic"}, "validated_against_schema_version": "1.2.5", "type": "somatic_mutation", "access_level": "public"}

Why is "type":"any" supported?

This is a possible bug. I need to figure out why type "any" is supported by JSON::Validator. Can it be that the json-schema draft4 have been changed..?

$ curl -s http://json-schema.org/draft-04/schema | grep -A1 '"simpleTypes"'
        "simpleTypes": {
            "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]

I also can't find it in the OpenAPI spec.

Should I remove support for "any"?

Using with alternative frameworks (Catalyst In our case).

I was bundled JSON::Validator into our Catalyst application but was LOL due to Mojolicious dependency.

Can I provide pull request with some updates like

  • Replace Mojo::File with Path::Class
  • Replace Mojo::JSON with JSON
  • Replace Mojo::Pointer with JSON::Pointer

etc.?

May need some extension/dependency injection points?

Undocumented "ref_key" arg to "bundle" needs documenting

The new ref_key argument that was added in 990bce6 needs documenting. It's important enough that the tests had it added too.

The doc should also mention that using e.g. $app->static->file('filename.yaml') as the "spec" won't work right since it does not get spotted as the same reference. What is needed is to use Mojo::File::realpath on that to get the canonical, ..-free file path! EDIT now in #99.

1.03 doesn't allow remote schemas with ids

Test case:
https://github.com/wbazant/json-validator/commit/27de57c1ae2c5022422919b69963cc4b32b845a0

#   Failed test 'remote ref - remote ref valid'
#   at t/acceptance.t line 52.
#          got: '0'
#     expected: '1'
# Invalid schema:
# /id: Does not match uri format. at /Users/wbazant/dev/json-validator/lib/JSON/Validator.pm line 70.
# 	JSON::Validator::load_and_validate_schema('JSON::Validator=HASH(0x7f91a1d0ccf8)', 'HASH(0x7f91a16efa18)') called at t/acceptance.t line 46
# 	eval {...} called at t/acceptance.t line 45

How does "ref" / bundles work with JSON::Validator?

I'd like to define a schema for one particular sub-structure in a file, and then re-use that in multiple schemas elsewhere. It appears that JSON::Validator supports this concept, but I can't figure out how it works (the test bundle.t didn't seem to enlighten me).

Basically the pattern I'm after here is:

car.json <- defines what is valid to be a car.

assembly_plant.json <- includes car.json uses it so it doesn't have to re-define it locally.
auto_showroom.json <- includes car.json, uses it so it doesn't have to re-define it locally.

This way I can alter car.json, and assembly_plant/auto_showroom will update accordingly.

Is this a thing? Do you have an example you can share?

Errors in anyOf validation. Do not understand the error messages

Hi,

It seems that in the validation process of a schema containing anyOf statements, the code issue errors for each of the attributes failing the test, regardless the anyOf branch that the test is. For example in the script jv-anyof.t in your test suite. In one of the tests:

@errors = $validator->validate("too long", $schema);

The $validator generate the following message:

anyOf failed: ([0] String is too long: 8/5. [1] Expected number - got string.)'

and I am only interested in knowing that the string is too long and not in the additional 'Expected number -got string' error.

Is there a way of generating only the 'String is to long' error?

Thanks,

ernesto

Duplicate error message while validate enums

Example:

#!/usr/bin/perl

use JSON::Validator;
use Mojo::JSON 'j';
use Mojo::Util 'dumper';

my $v = JSON::Validator->new;
$v->schema('data://main/test.schema');

my $data = j '{"foo": "x"}';
my @errors = $v->validate($data);
print dumper \@errors;

__DATA__

@@ test.schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "test",
  "type": "object",
  "properties": {
    "foo": {"enum": ["bar", "baz"]}
  }
}

And output:

[
  bless( {
    "message" => "Not in enum list: bar, baz.",
    "path" => "/foo"
  }, 'JSON::Validator::Error' ),
  bless( {
    "message" => "Not in enum list: bar, baz.",
    "path" => "/foo"
  }, 'JSON::Validator::Error' )
]

Versions:

$ perl -MV=Mojolicious,JSON::Validator
Mojolicious
    /usr/local/share/perl/5.22.1/Mojolicious.pm: 7.0
JSON::Validator
    /usr/local/share/perl/5.22.1/JSON/Validator.pm: 0.75
$

Where/How to implement date-time format coercer?

I'm looking for guidance on the best place to put date-time coercion logic. My guess is that it would belong in a JSON::Validator::OpenAPI subclass - or possibly JSON::Validator::OpenAPI itself since Mojolicious is a PREREQ_PM, supplying Mojo::Date to handle date logic without brining in DateTime?

A naive example of the coercer could be:

# monkey_patch only to install a hyphenated method name for later call to $self->$openapi_type_name(...)
monkey_patch(__PACKAGE__,
    '_validate_date-time' => sub {
        my ($self, $value, $path, $schema, $expected) = @_;
        return $self->_is_date_time($value) if !$self->{coerce}{"date-time"} or ($value = Mojo::Date->new($value)->to_datetime);
    },
);

My confusion is that date-time is a format, where it could be argued coercion is a grey area (and no coercion is done on any of the existing formats). Specifically I'm interested in accepting spaces (or any character) per RFC3339 in place of T and Z which could be handled by modifying _is_date_time regex, but I know eventually we're going to need to solve accepting other valid ISO8601 datetimes (possibly defined as a swagger string type using pattern) and coercing to RFC3339.

Thanks for any advice you can give me!

Request with $ref parameter can't be validated against schema without setting allow_invalid_ref to true

I have a schema with a path object like this

  /hit:
    post:
      operationId: v1_hit
      x-mojo-to: rest_api-v1#hit
      summary: register new hit
      produces:
      - application/json
      parameters:
      - $ref: "#/parameters/apiKey"
      - name: body
        in: body
        required: true
        schema:
          $ref: "#/definitions/hit"
      responses:
        '202':
          description: ''
          examples:
            application/json:
              status: ok
        '500':
          description: "Internal server error"
        '401':
          description: "Authorization failed"
        '400':
          description: "Bad Request"

Unless i set allow_invalid_ref to true while initializing Mojolicious::Plugin, I get error Unsupported $in: . Please report at https://github.com/jhthorsen/json-validator at /home/irassadin/Relap/script/../local/lib/perl5/JSON/Validator/OpenAPI.pm line 296.

So, as far as i can see it's a bug.
First of all, using reference inside parameters is valid (see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#path-item-object).
And second, I have no error about invalid schema, but get a validation error for request.

Errors while building 1.02

While trying to build this version for the Mageia Linux Ditribution, I have these 4 errors:


#   Failed test 'errors: /v: Does not match uri format.'
#   at t/Helper.pm line 16.
#     Structures begin differing at:
#          $got->[0] = Does not exist
#     $expected->[0] = HASH(0x2a4c090)
# []
Format rule for 'unknown' is missing at /users/bruno/Maison/bruno/prj/mageia/perl-JSON-Validator/BUILD/JSON-Validator-1.02/blib/lib/JSON/Validator.pm line 478.
# Looks like you failed 1 test of 28.
t/jv-formats.t ......................... 
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/28 subtests 

#   Failed test 'errors: /credit_card: Missing billing_address.'
#   at t/Helper.pm line 16.
#     Structures begin differing at:
#          $got->[0] = Does not exist
#     $expected->[0] = HASH(0x2ef9938)
# []
# Looks like you failed 1 test of 19.
t/jv-object.t .......................... 
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/19 subtests 

#   Failed test 'errors: /v: Does not match float format.'
#   at t/Helper.pm line 16.
#     Structures begin differing at:
#          $got->[0] = Does not exist
#     $expected->[0] = HASH(0x313b2a8)
# []

#   Failed test 'errors: /v: Does not match uri format.'
#   at t/Helper.pm line 16.
#     Structures begin differing at:
#          $got->[0] = Does not exist
#     $expected->[0] = HASH(0x3146740)
# []
Format rule for 'unknown' is missing at /users/bruno/Maison/bruno/prj/mageia/perl-JSON-Validator/BUILD/JSON-Validator-1.02/blib/lib/JSON/Validator.pm line 478.
# Looks like you failed 2 tests of 24.
t/openapi-formats.t .................... 
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/24 subtests 

Any idea what could be the issue here ?
TIA,
Bruno.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.