--- /dev/null
+#!/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--;
+}
--- /dev/null
+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;
## 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);
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);
+}