Skip to content

Commit

Permalink
make sure operationId is unique globally
Browse files Browse the repository at this point in the history
The Mojolicious::Plugin::OpenAPI uses the `operationId` to name the
route, so if two routes with the same name exist, the last one wins,
even if that route is defined by another API file.
  • Loading branch information
preaction committed May 11, 2017
1 parent c27c5ec commit ef28b25
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 20 deletions.
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ document is used by
[Mojolicious::Plugin::OpenAPI](http://metacpan.org/pod/Mojolicious::Plugin::OpenAPI)
to generate the Mojolicious routes and validate the input and output
automatically. Each route should have an `x-mojo-to` key to link it to
a `controller` (class) and `action` (method).
a `controller` (class) and `action` (method). It should also have an
`operationId` that is globally unique for all API files.

##### `share/templates`

Expand Down
14 changes: 7 additions & 7 deletions share/v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"controller": "Report",
"action": "report"
},
"operationId": "addReport",
"operationId": "v3_report_post",
"parameters": [{
"name": "report",
"in": "body",
Expand Down Expand Up @@ -75,7 +75,7 @@
"/release": {
"get": {
"tags": [ "Release" ],
"operationId": "release_all",
"operationId": "v3_release_all",
"summary": "Get summary test report info about all CPAN releases",
"x-mojo-to": {
"controller": "Release",
Expand All @@ -100,7 +100,7 @@
"/release/dist/{dist}": {
"get": {
"tags": [ "Release" ],
"operationId": "release_dist",
"operationId": "v3_release_dist",
"summary": "Get summary test report info for releases of a distribution",
"x-mojo-to": {
"controller": "Release",
Expand Down Expand Up @@ -129,7 +129,7 @@
"/release/author/{author}": {
"get": {
"tags": [ "Release" ],
"operationId": "release_author",
"operationId": "v3_release_author",
"summary": "Get summary test report info for releases by an author",
"x-mojo-to": {
"controller": "Release",
Expand Down Expand Up @@ -158,7 +158,7 @@
"/upload": {
"get": {
"tags": [ "Upload" ],
"operationId": "upload_all",
"operationId": "v3_upload_all",
"summary": "Get all uploads to CPAN",
"description": "This route gets uploads to CPAN. Asking for a WebSocket will subscribe to a feed of new uploads.",
"x-mojo-to": {
Expand Down Expand Up @@ -187,7 +187,7 @@
"/upload/dist/{dist}": {
"get": {
"tags": [ "Upload" ],
"operationId": "upload_dist",
"operationId": "v3_upload_dist",
"summary": "Get uploads for a dist",
"description": "This route gets uploads to CPAN for a specific distribution. Asking for a WebSocket will subscribe to a feed of new uploads.",
"x-mojo-to": {
Expand Down Expand Up @@ -217,7 +217,7 @@
"/upload/author/{author}": {
"get": {
"tags": [ "Upload" ],
"operationId": "upload_author",
"operationId": "v3_upload_author",
"summary": "Get uploads for an author",
"description": "This route gets uploads to CPAN for the specific author. Asking for a WebSocket will subscribe to a feed of new uploads.",
"x-mojo-to": {
Expand Down
24 changes: 12 additions & 12 deletions t/controller/upload.t
Original file line number Diff line number Diff line change
Expand Up @@ -62,32 +62,32 @@ for \my %upload ( $data{ Upload }->@* ) {
}

subtest 'all uploads' => sub {
$t->get_ok( '/v1/upload' )
$t->get_ok( '/v3/upload' )
->status_is( 200 )
->json_is( [ map { +{ $_->%{ @API_FIELDS } } } $data{Upload}->@[0..2] ] )
->or( sub { diag explain $_[0]->tx->res->json } );

subtest 'since' => sub {
$t->get_ok( '/v1/upload?since=2016-11-19T03:05:00Z' )
$t->get_ok( '/v3/upload?since=2016-11-19T03:05:00Z' )
->status_is( 200 )
->json_is( [ map { +{ $_->%{ @API_FIELDS } } } $data{Upload}->@[1..2] ] )
->or( sub { diag explain $_[0]->tx->res->json } );
};
};

subtest 'by dist' => sub {
$t->get_ok( '/v1/upload/dist/My-Dist' )
$t->get_ok( '/v3/upload/dist/My-Dist' )
->status_is( 200 )
->json_is( [ map { +{ $_->%{ @API_FIELDS } } } $data{Upload}->@[0,1] ] );

subtest 'since' => sub {
$t->get_ok( '/v1/upload/dist/My-Dist?since=2016-11-19T03:05:00Z' )
$t->get_ok( '/v3/upload/dist/My-Dist?since=2016-11-19T03:05:00Z' )
->status_is( 200 )
->json_is( [ map { +{ $_->%{ @API_FIELDS } } } $data{Upload}[1] ] );
};

subtest 'dist not found' => sub {
$t->get_ok( '/v1/upload/dist/NOT_FOUND' )
$t->get_ok( '/v3/upload/dist/NOT_FOUND' )
->status_is( 404 )
->json_is( {
errors => [ { message => 'Distribution "NOT_FOUND" not found', 'path' => '/' } ],
Expand All @@ -96,18 +96,18 @@ subtest 'by dist' => sub {
};

subtest 'by author' => sub {
$t->get_ok( '/v1/upload/author/PREACTION' )
$t->get_ok( '/v3/upload/author/PREACTION' )
->status_is( 200 )
->json_is( [ map { +{ $_->%{ @API_FIELDS } } } $data{Upload}->@[0,2] ] );

subtest 'since' => sub {
$t->get_ok( '/v1/upload/author/PREACTION?since=2016-11-19T03:05:00Z' )
$t->get_ok( '/v3/upload/author/PREACTION?since=2016-11-19T03:05:00Z' )
->status_is( 200 )
->json_is( [ map { +{ $_->%{ @API_FIELDS } } } $data{Upload}[2] ] );
};

subtest 'author not found' => sub {
$t->get_ok( '/v1/upload/author/NOT_FOUND' )
$t->get_ok( '/v3/upload/author/NOT_FOUND' )
->status_is( 404 )
->json_is( {
errors => [ { message => 'Author "NOT_FOUND" not found', path => '/' } ],
Expand All @@ -118,7 +118,7 @@ subtest 'by author' => sub {
subtest 'input validation' => sub {

subtest '"since" must be an ISO8601 date/time' => sub {
$t->get_ok( '/v1/upload/dist/My-Dist?since=Sat Nov 19 14:18:40 2016' )
$t->get_ok( '/v3/upload/dist/My-Dist?since=Sat Nov 19 14:18:40 2016' )
->status_is( 400 )
->json_has( '/errors' )
->or( sub { diag explain shift->tx->res->json } );
Expand Down Expand Up @@ -146,13 +146,13 @@ subtest 'websocket feeds' => sub {
my $broker_url = $broker->ua->server->nb_url;
$t->app->config->{broker} = 'ws://' . $broker_url->host_port;

$t->websocket_ok( '/v1/upload' )
$t->websocket_ok( '/v3/upload' )
->message_ok
->message_is( 'Got topic: upload/dist', 'default to all uploaded dists' )
;

my $peer = Test::Mojo->new( $t->app );
$peer->websocket_ok( '/v1/upload/dist/Statocles' )
$peer->websocket_ok( '/v3/upload/dist/Statocles' )
->message_ok
->message_is( 'Got topic: upload/dist/Statocles' )
->finish_ok;
Expand All @@ -162,7 +162,7 @@ subtest 'websocket feeds' => sub {
->finish_ok
;

$t->websocket_ok( '/v1/upload/author/STOP' )
$t->websocket_ok( '/v3/upload/author/STOP' )
->message_ok
->message_is( 'Got topic: upload/author/STOP' )
->finish_ok
Expand Down

0 comments on commit ef28b25

Please sign in to comment.