jhthorsen / mojolicious-plugin-openapi

OpenAPI / Swagger plugin for Mojolicious
54 stars 42 forks source link

V3: Nullable and references don't work together #183

Closed NGEfreak closed 4 years ago

NGEfreak commented 4 years ago

When I define an attribute as nullable in a base object and reference this attribute in another object then the attribute only allows null and not the main type.

Here is an example test (last request fails and returns the error "Expected null - got string"):

#!/usr/bin/env perl

use 5.010;
use strict;
use warnings;
use utf8;

use Test::More;
use Test::Mojo;

use Mojolicious::Lite;

post '/test-base' => sub {
    my $c = shift->openapi->valid_input or return;
    my $output = $c->req->json;
    $c->render(openapi => $output, status => 200);
}, 'test1';

post '/test-ref' => sub {
    my $c = shift->openapi->valid_input or return;
    my $output = $c->req->json;
    $c->render(openapi => $output, status => 200);
}, 'test2';

plugin OpenAPI => {
    url    => 'data:///api.yml',
    schema => 'v3',
};

my $t = Test::Mojo->new();

# Base object; In/Output null
$t->post_ok('/test-base' => json => { foo => undef })
    ->status_is(200)
    ->json_is({ foo => undef });

# Base object; In/Output string
$t->post_ok('/test-base' => json => { foo => 'test' })
    ->status_is(200)
    ->json_is({ foo => 'test' });

# Reference object; In/Output null
$t->post_ok('/test-ref' => json => { foo => undef })
    ->status_is(200)
    ->json_is({ foo => undef });

# Reference object; In/Output string
$t->post_ok('/test-ref' => json => { foo => 'test' })
    ->status_is(200)
    ->json_is({ foo => 'test' });

done_testing;

__DATA__

@@ api.yml
openapi: 3.0.0
info:
  title: Test
  version: 0.0.0
paths:
  /test-base:
    post:
      x-mojo-name: test1
      requestBody:
        required: true
        content:
         application/json:
          schema:
            $ref: '#/components/schemas/Test'
      responses:
        '200':
          description: ok
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Test'
  /test-ref:
    post:
      x-mojo-name: test2
      requestBody:
        required: true
        content:
         application/json:
          schema:
            $ref: '#/components/schemas/TestRef'
      responses:
        '200':
          description: ok
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestRef'
components:
  schemas:
    Test:
      properties:
        foo:
          type: string
          nullable: true
    TestRef:
      properties:
        foo:
          $ref: '#/components/schemas/Test/properties/foo'

It looks like the problem is in line 481 of JSON::Validator::OpenAPI::Mojolicious. When I remove this line it works. The other tests also still work, but I don't know what further consequences this removal would do.

jhthorsen commented 4 years ago

Thanks for a very nice bug report! The fixed version will be available soon.