Bug 21116: Unit tests
authorTomas Cohen Arazi <tomascohen@theke.io>
Mon, 27 Aug 2018 19:24:09 +0000 (16:24 -0300)
committerFridolin Somers <fridolin.somers@biblibre.com>
Thu, 29 Nov 2018 12:25:16 +0000 (13:25 +0100)
This path implements unit tests for the route-from-plugin development.
It adds the required methods to the Koha::Plugin::Test plugin
distributed along with the tests. A second plugin implementing invalid
OpenAPI specs is added (Koha::Plugin::BadAPIRoute).

Edit: I made terminology changes to make it less rude.

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Alex Arnaud <alex.arnaud@biblibre.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
(cherry picked from commit 46c992948ea28ae2bebc7f9042df6434319b80bf)
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
(cherry picked from commit f243f8f0123a29752f37df0cc8ad25a49ba066e6)
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>

t/db_dependent/Koha/REST/Plugin/PluginRoutes.t [new file with mode: 0644]
t/lib/Koha/Plugin/BadAPIRoute.pm [new file with mode: 0644]
t/lib/Koha/Plugin/Test.pm

diff --git a/t/db_dependent/Koha/REST/Plugin/PluginRoutes.t b/t/db_dependent/Koha/REST/Plugin/PluginRoutes.t
new file mode 100644 (file)
index 0000000..06fecd3
--- /dev/null
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 1;
+use Test::Mojo;
+use Test::Warn;
+
+use File::Basename;
+use t::lib::Mocks;
+
+use JSON::Validator::OpenAPI::Mojolicious;
+
+# Dummy app for testing the plugin
+use Mojolicious::Lite;
+
+BEGIN {
+    # Mock pluginsdir before loading Plugins module
+    my $path = dirname(__FILE__) . '/../../../../lib';
+    t::lib::Mocks::mock_config( 'pluginsdir', $path );
+}
+
+subtest 'Bad plugins tests' => sub {
+
+    plan tests => 3;
+
+    # enable plugins
+    t::lib::Mocks::mock_config( 'enable_plugins', 1 );
+    t::lib::Mocks::mock_preference( 'UseKohaPlugins', 1 );
+
+    # initialize Koha::REST::V1 after mocking
+    my $remote_address = '127.0.0.1';
+    my $t;
+
+    warning_is
+        { $t = Test::Mojo->new('Koha::REST::V1'); }
+        'The resulting spec is invalid. Skipping Bad API Route Plugin',
+        'Bad plugins raise warning';
+
+    my $routes = get_defined_routes($t);
+    ok( !exists $routes->{'/contrib/badass/patrons/(:patron_id)/bother_wrong'}, 'Route doesn\'t exist' );
+    ok( exists $routes->{'/contrib/testplugin/patrons/(:patron_id)/bother'}, 'Route exists' );
+
+};
+
+sub get_defined_routes {
+    my ($t) = @_;
+    my $routes = {};
+    traverse_routes( $_, 0, $routes ) for @{ $t->app->routes->children };
+
+    return $routes;
+}
+
+sub traverse_routes {
+    my ( $route, $depth, $routes ) = @_;
+
+    # Pattern
+    my $path = $route->pattern->unparsed || '/';
+
+    # Methods
+    my $via = $route->via;
+    my $verb = !$via ? '*' : uc join ',', @$via;
+    $routes->{$path}->{$verb} = 1;
+
+    $depth++;
+    traverse_routes( $_, $depth, $routes ) for @{ $route->children };
+    $depth--;
+}
diff --git a/t/lib/Koha/Plugin/BadAPIRoute.pm b/t/lib/Koha/Plugin/BadAPIRoute.pm
new file mode 100644 (file)
index 0000000..baf7e23
--- /dev/null
@@ -0,0 +1,92 @@
+package Koha::Plugin::BadAPIRoute;
+
+use Modern::Perl;
+
+use Mojo::JSON qw(decode_json);
+
+use base qw(Koha::Plugins::Base);
+
+our $VERSION = 0.01;
+our $metadata = {
+    name            => 'Bad API Route Plugin',
+    author          => 'John Doe',
+    description     => 'Test plugin for bad API route',
+    date_authored   => '2018-',
+    date_updated    => '2013-01-14',
+    minimum_version => '17.11',
+    maximum_version => undef,
+    version         => $VERSION,
+    my_example_tag  => 'find_me',
+};
+
+sub new {
+    my ( $class, $args ) = @_;
+    $args->{'metadata'} = $metadata;
+    my $self = $class->SUPER::new($args);
+    return $self;
+}
+
+sub api_namespace {
+    return "badass";
+}
+
+sub api_routes {
+    my ( $self, $args ) = @_;
+
+    my $spec = qq{
+{
+  "/patrons/{patron_id}/bother_wrong": {
+    "put": {
+      "x-mojo-to": "Koha::Plugin::BadAPIRoute#bother",
+      "operationId": "BotherPatron",
+      "tags": ["patrons"],
+      "parameters": [{
+        "name": "patron_id",
+        "in": "nowhere",
+        "description": "Internal patron identifier",
+        "required": true,
+        "type": "integer"
+      }],
+      "produces": [
+        "application/json"
+      ],
+      "responses": {
+        "200": {
+          "description": "A bothered patron",
+          "schema": {
+              "type": "object",
+                "properties": {
+                  "bothered": {
+                    "description": "If the patron has been bothered",
+                    "type": "boolean"
+                  }
+                }
+          }
+        },
+        "404": {
+          "description": "An error occurred",
+          "schema": {
+              "type": "object",
+                "properties": {
+                  "error": {
+                    "description": "An explanation for the error",
+                    "type": "string"
+                  }
+                }
+          }
+        }
+      },
+      "x-koha-authorization": {
+        "permissions": {
+          "borrowers": "1"
+        }
+      }
+    }
+  }
+}
+    };
+
+    return decode_json($spec);
+}
+
+1;
index d01cc28..2cb749e 100644 (file)
@@ -3,6 +3,8 @@ package Koha::Plugin::Test;
 ## It's good practice to use Modern::Perl
 use Modern::Perl;
 
+use Mojo::JSON qw(decode_json);
+
 ## Required for all plugins
 use base qw(Koha::Plugins::Base);
 
@@ -117,3 +119,66 @@ sub test_output_html {
     my ( $self ) = @_;
     $self->output_html( '¡Hola output_html!' );
 }
+
+sub api_namespace {
+    return "testplugin";
+}
+
+sub api_routes {
+    my ( $self, $args ) = @_;
+
+    my $spec = qq{
+{
+  "/patrons/{patron_id}/bother": {
+    "put": {
+      "x-mojo-to": "Koha::Plugin::Test#bother",
+      "operationId": "BotherPatron",
+      "tags": ["patrons"],
+      "parameters": [{
+        "name": "patron_id",
+        "in": "path",
+        "description": "Internal patron identifier",
+        "required": true,
+        "type": "integer"
+      }],
+      "produces": [
+        "application/json"
+      ],
+      "responses": {
+        "200": {
+          "description": "A bothered patron",
+          "schema": {
+              "type": "object",
+                "properties": {
+                  "bothered": {
+                    "description": "If the patron has been bothered",
+                    "type": "boolean"
+                  }
+                }
+          }
+        },
+        "404": {
+          "description": "An error occurred",
+          "schema": {
+              "type": "object",
+                "properties": {
+                  "error": {
+                    "description": "An explanation for the error",
+                    "type": "string"
+                  }
+                }
+          }
+        }
+      },
+      "x-koha-authorization": {
+        "permissions": {
+          "borrowers": "1"
+        }
+      }
+    }
+  }
+}
+    };
+
+    return decode_json($spec);
+}