@@ -42,36 +42,23 @@ subtest 'basic construction' => sub {
4242 );
4343};
4444
45- subtest ' top level document fields' => sub {
46- my $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
47- canonical_uri => ' http://localhost:1234/api' ,
48- evaluator => my $js = JSON::Schema::Modern-> new,
49- schema => 1,
50- );
51-
52- cmp_result(
53- [ map $_ -> TO_JSON, $doc -> errors ],
54- [
55- {
56- instanceLocation => ' ' ,
57- keywordLocation => ' /type' ,
58- absoluteKeywordLocation => DEFAULT_METASCHEMA.' #/type' ,
59- error => ' got integer, not object' ,
60- },
61- ],
45+ subtest ' top level document checks' => sub {
46+ die_result(
47+ sub {
48+ JSON::Schema::Modern::Document::OpenAPI-> new(
49+ canonical_uri => ' http://localhost:1234/api' ,
50+ evaluator => JSON::Schema::Modern-> new,
51+ schema => 1,
52+ );
53+ },
54+ qr / ^Value "1" did not pass type constraint "HashRef"/ ,
6255 ' document is wrong type' ,
6356 );
6457
65- is(
66- document_result($doc ),
67- q! '': got integer, not object! ,
68- ' stringified errors' ,
69- );
7058
71-
72- $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
59+ my $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
7360 canonical_uri => ' http://localhost:1234/api' ,
74- evaluator => $js = JSON::Schema::Modern-> new,
61+ evaluator => my $js = JSON::Schema::Modern-> new,
7562 schema => {},
7663 );
7764 cmp_result(
@@ -190,6 +177,45 @@ ERRORS
190177ERRORS
191178
192179
180+ $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
181+ canonical_uri => ' http://localhost:1234/api' ,
182+ evaluator => $js ,
183+ schema => {
184+ openapi => OAS_VERSION,
185+ info => {
186+ title => ' my title' ,
187+ version => ' 1.2.3' ,
188+ },
189+ ' $self' => ' #frag\\ ment' ,
190+ },
191+ );
192+
193+ cmp_result(
194+ [ map $_ -> TO_JSON, $doc -> errors ],
195+ [
196+ {
197+ instanceLocation => ' /$self' ,
198+ keywordLocation => ' /properties/$self/pattern' ,
199+ absoluteKeywordLocation => DEFAULT_METASCHEMA.' #/properties/$self/pattern' ,
200+ error => ' $self cannot contain a fragment' ,
201+ },
202+ {
203+ instanceLocation => ' /$self' ,
204+ keywordLocation => ' /properties/$self/format' ,
205+ absoluteKeywordLocation => DEFAULT_METASCHEMA.' #/properties/$self/format' ,
206+ error => ' not a valid uri-reference string' ,
207+ },
208+ {
209+ instanceLocation => ' ' ,
210+ keywordLocation => ' /properties' ,
211+ absoluteKeywordLocation => DEFAULT_METASCHEMA.' #/properties' ,
212+ error => ' not all properties are valid' ,
213+ },
214+ ],
215+ ' invalid $self uri, with custom error message' ,
216+ );
217+
218+
193219 $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
194220 canonical_uri => ' http://localhost:1234/api' ,
195221 evaluator => $js ,
@@ -463,6 +489,138 @@ ERRORS
463489 }),
464490 ' dialect resources are properly stored on the evaluator' ,
465491 );
492+
493+
494+ # relative $self, absolute original_uri - $self is resolved with original_uri
495+ $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
496+ canonical_uri => ' http://localhost:1234/foo/api.json' ,
497+ evaluator => $js ,
498+ schema => {
499+ openapi => OAS_VERSION,
500+ info => {
501+ title => ' my title' ,
502+ version => ' 1.2.3' ,
503+ },
504+ ' $self' => ' user/api.json' , # the 'user' family of APIs
505+ paths => {},
506+ },
507+ );
508+
509+ is($doc -> original_uri, ' http://localhost:1234/foo/api.json' , ' retrieval uri' );
510+ is($doc -> canonical_uri, ' http://localhost:1234/foo/user/api.json' , ' canonical uri is $self resolved against retrieval uri' );
511+ cmp_deeply(
512+ $doc -> {resource_index },
513+ {
514+ ' http://localhost:1234/foo/user/api.json' => {
515+ canonical_uri => str(' http://localhost:1234/foo/user/api.json' ),
516+ path => ' ' ,
517+ specification_version => ' draft2020-12' ,
518+ vocabularies => bag(map ' JSON::Schema::Modern::Vocabulary::' .$_ ,
519+ qw( Core Applicator Validation FormatAnnotation Content MetaData Unevaluated OpenAPI) ),
520+ configs => {},
521+ },
522+ },
523+ ' resource is properly indexed' ,
524+ );
525+
526+
527+ # absolute $self, absolute original_uri - $self is used as is
528+ $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
529+ canonical_uri => ' http://localhost:1234/foo/api.json' ,
530+ evaluator => $js ,
531+ schema => {
532+ openapi => OAS_VERSION,
533+ info => {
534+ title => ' my title' ,
535+ version => ' 1.2.3' ,
536+ },
537+ ' $self' => ' http://localhost:5555/user/api.json' , # the 'user' family of APIs
538+ paths => {},
539+ },
540+ );
541+
542+ is($doc -> original_uri, ' http://localhost:1234/foo/api.json' , ' retrieval uri' );
543+ is($doc -> canonical_uri, ' http://localhost:5555/user/api.json' , ' canonical uri is $self, already absolute' );
544+ cmp_deeply(
545+ $doc -> {resource_index },
546+ {
547+ ' http://localhost:5555/user/api.json' => {
548+ canonical_uri => str(' http://localhost:5555/user/api.json' ),
549+ path => ' ' ,
550+ specification_version => ' draft2020-12' ,
551+ vocabularies => bag(map ' JSON::Schema::Modern::Vocabulary::' .$_ ,
552+ qw( Core Applicator Validation FormatAnnotation Content MetaData Unevaluated OpenAPI) ),
553+ configs => {},
554+ },
555+ },
556+ ' resource is properly indexed' ,
557+ );
558+
559+
560+ # relative $self, relative original_uri - $self is resolved with original_uri
561+ $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
562+ canonical_uri => ' foo/api.json' ,
563+ evaluator => $js ,
564+ schema => {
565+ openapi => OAS_VERSION,
566+ info => {
567+ title => ' my title' ,
568+ version => ' 1.2.3' ,
569+ },
570+ ' $self' => ' user/api.json' , # the 'user' family of APIs
571+ paths => {},
572+ },
573+ );
574+
575+ is($doc -> original_uri, ' foo/api.json' , ' retrieval uri' );
576+ is($doc -> canonical_uri, ' foo/user/api.json' , ' canonical uri is $self resolved against retrieval uri' );
577+ cmp_deeply(
578+ $doc -> {resource_index },
579+ {
580+ ' foo/user/api.json' => {
581+ canonical_uri => str(' foo/user/api.json' ),
582+ path => ' ' ,
583+ specification_version => ' draft2020-12' ,
584+ vocabularies => bag(map ' JSON::Schema::Modern::Vocabulary::' .$_ ,
585+ qw( Core Applicator Validation FormatAnnotation Content MetaData Unevaluated OpenAPI) ),
586+ configs => {},
587+ },
588+ },
589+ ' resource is properly indexed' ,
590+ );
591+
592+
593+ # absolute $self, relative original_uri - $self is used as is
594+ $doc = JSON::Schema::Modern::Document::OpenAPI-> new(
595+ canonical_uri => ' foo/api.json' ,
596+ evaluator => $js ,
597+ schema => {
598+ openapi => OAS_VERSION,
599+ info => {
600+ title => ' my title' ,
601+ version => ' 1.2.3' ,
602+ },
603+ ' $self' => ' http://localhost:5555/user/api.json' , # the 'user' family of APIs
604+ paths => {},
605+ },
606+ );
607+
608+ is($doc -> original_uri, ' foo/api.json' , ' retrieval uri' );
609+ is($doc -> canonical_uri, ' http://localhost:5555/user/api.json' , ' canonical uri is $self, already absolute' );
610+ cmp_deeply(
611+ $doc -> {resource_index },
612+ {
613+ ' http://localhost:5555/user/api.json' => {
614+ canonical_uri => str(' http://localhost:5555/user/api.json' ),
615+ path => ' ' ,
616+ specification_version => ' draft2020-12' ,
617+ vocabularies => bag(map ' JSON::Schema::Modern::Vocabulary::' .$_ ,
618+ qw( Core Applicator Validation FormatAnnotation Content MetaData Unevaluated OpenAPI) ),
619+ configs => {},
620+ },
621+ },
622+ ' resource is properly indexed' ,
623+ );
466624};
467625
468626done_testing;
0 commit comments