From f243f8f0123a29752f37df0cc8ad25a49ba066e6 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Mon, 27 Aug 2018 16:24:09 -0300 Subject: [PATCH] Bug 21116: Unit tests 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 Signed-off-by: Alex Arnaud Signed-off-by: Nick Clemens (cherry picked from commit 46c992948ea28ae2bebc7f9042df6434319b80bf) Signed-off-by: Martin Renvoize --- .../Koha/REST/Plugin/PluginRoutes.t | 83 +++++++++++++++++ t/lib/Koha/Plugin/BadAPIRoute.pm | 92 +++++++++++++++++++ t/lib/Koha/Plugin/Test.pm | 65 +++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 t/db_dependent/Koha/REST/Plugin/PluginRoutes.t create mode 100644 t/lib/Koha/Plugin/BadAPIRoute.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 index 0000000000..06fecd38fa --- /dev/null +++ b/t/db_dependent/Koha/REST/Plugin/PluginRoutes.t @@ -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 . + +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 index 0000000000..baf7e23a3f --- /dev/null +++ b/t/lib/Koha/Plugin/BadAPIRoute.pm @@ -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; diff --git a/t/lib/Koha/Plugin/Test.pm b/t/lib/Koha/Plugin/Test.pm index 3452af9302..f817438986 100644 --- a/t/lib/Koha/Plugin/Test.pm +++ b/t/lib/Koha/Plugin/Test.pm @@ -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); @@ -92,3 +94,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); +} -- 2.39.5