3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use Test::More tests => 4;
27 use JSON::Validator::OpenAPI::Mojolicious;
29 # Dummy app for testing the plugin
30 use Mojolicious::Lite;
33 # Mock pluginsdir before loading Plugins module
34 my $path = dirname(__FILE__) . '/../../../../lib';
35 t::lib::Mocks::mock_config( 'pluginsdir', $path );
41 my $schema = Koha::Database->new->schema;
43 subtest 'Bad plugins tests' => sub {
47 $schema->storage->txn_begin;
50 t::lib::Mocks::mock_config( 'enable_plugins', 1 );
52 # remove any existing plugins that might interfere
53 Koha::Plugins::Methods->search->delete;
54 my $plugins = Koha::Plugins->new;
55 $plugins->InstallPlugins;
57 my @plugins = $plugins->GetPlugins( { all => 1 } );
58 foreach my $plugin (@plugins) {
62 # initialize Koha::REST::V1 after mocking
65 { $t = Test::Mojo->new('Koha::REST::V1'); }
66 'The resulting spec is invalid. Skipping Bad API Route Plugin',
67 'Bad plugins raise warning';
69 my $routes = get_defined_routes($t);
70 # Support placeholders () and <> (latter style used starting with Mojolicious::Plugin::OpenAPI@1.28)
71 # TODO: remove () if minimum version is bumped to at least 1.28.
72 ok( !exists $routes->{'/contrib/badass/patrons/bother_wrong'}, 'Route doesn\'t exist' );
73 ok( exists $routes->{'/contrib/testplugin/patrons/bother'}, 'Route exists' );
75 $schema->storage->txn_rollback;
78 subtest 'Disabled plugins tests' => sub {
82 $schema->storage->txn_begin;
85 t::lib::Mocks::mock_config( 'enable_plugins', 1 );
89 my $plugins = Koha::Plugins->new;
90 $plugins->InstallPlugins;
92 my @plugins = $plugins->GetPlugins( { all => 1 } );
93 foreach my $plugin (@plugins) {
95 $good_plugin = $plugin
96 if $plugin->{metadata}->{description} eq 'Test plugin';
99 # initialize Koha::REST::V1 after mocking
100 my $t = Test::Mojo->new('Koha::REST::V1');
102 my $routes = get_defined_routes($t);
103 # Support placeholders () and <> (latter style used starting with Mojolicious::Plugin::OpenAPI@1.28)
104 # TODO: remove () if minimum version is bumped to at least 1.28.
105 ok( !exists $routes->{'/contrib/testplugin/patrons/bother'},
106 'Plugin disabled, route not defined' );
108 $good_plugin->enable;
110 $t = Test::Mojo->new('Koha::REST::V1');
111 $routes = get_defined_routes($t);
113 # Support placeholders () and <> (latter style used starting with Mojolicious::Plugin::OpenAPI@1.28)
114 # TODO: remove () if minimum version is bumped to at least 1.28.
115 ok( exists $routes->{'/contrib/testplugin/patrons/bother'},
116 'Plugin enabled, route defined' );
118 $schema->storage->txn_rollback;
121 subtest 'Anonymous access routes plugins tests' => sub {
125 $schema->storage->txn_begin;
128 t::lib::Mocks::mock_config( 'enable_plugins', 1 );
130 # remove any existing plugins that might interfere
131 Koha::Plugins::Methods->search->delete;
132 my $plugins = Koha::Plugins->new;
133 $plugins->InstallPlugins;
135 my @plugins = $plugins->GetPlugins( { all => 1 } );
136 foreach my $plugin (@plugins) {
140 # initialize Koha::REST::V1 after mocking
143 { $t = Test::Mojo->new('Koha::REST::V1'); }
144 'The resulting spec is invalid. Skipping Bad API Route Plugin',
145 'Bad plugins raise warning';
147 my $routes = get_defined_routes($t);
148 ok( exists $routes->{'/contrib/testplugin/patrons/bother'}, 'Route exists' );
149 ok( exists $routes->{'/contrib/testplugin/public/patrons/bother'}, 'Route exists' );
151 C4::Context->set_preference( 'RESTPublicAnonymousRequests', 0 );
153 $t->get_ok('/api/v1/contrib/testplugin/public/patrons/bother')
154 ->status_is(200, 'Plugin routes not affected by RESTPublicAnonymousRequests')
155 ->json_is( { bothered => Mojo::JSON->true } );
157 C4::Context->set_preference( 'RESTPublicAnonymousRequests', 1 );
159 $t->get_ok('/api/v1/contrib/testplugin/public/patrons/bother')
160 ->status_is(200, 'Plugin routes not affected by RESTPublicAnonymousRequests')
161 ->json_is( { bothered => Mojo::JSON->true } );
163 $schema->storage->txn_rollback;
166 subtest 'needs_install use case tests' => sub {
170 $schema->storage->txn_begin;
173 t::lib::Mocks::mock_config( 'enable_plugins', 1 );
177 my $plugins = Koha::Plugins->new;
178 $plugins->InstallPlugins;
180 # mock Version before initializing the API class
181 t::lib::Mocks::mock_preference('Version', undef);
182 # initialize Koha::REST::V1 after mocking
184 my $t = Test::Mojo->new('Koha::REST::V1');
185 my $routes = get_defined_routes($t);
187 # Support placeholders () and <> (latter style used starting with Mojolicious::Plugin::OpenAPI@1.28)
188 # TODO: remove () if minimum version is bumped to at least 1.28.
190 !exists $routes->{'/contrib/testplugin/patrons/bother'},
191 'Plugin enabled, route not defined as C4::Context->needs_install is true'
194 t::lib::Mocks::mock_preference('Version', '3.0.0');
196 $schema->resultset('PluginData')->delete;
197 $plugins->InstallPlugins;
199 # re-initialize Koha::REST::V1 after mocking
200 $t = Test::Mojo->new('Koha::REST::V1');
201 $routes = get_defined_routes($t);
203 # Support placeholders () and <> (latter style used starting with Mojolicious::Plugin::OpenAPI@1.28)
204 # TODO: remove () if minimum version is bumped to at least 1.28.
206 exists $routes->{'/contrib/testplugin/patrons/bother'},
207 'Plugin enabled, route defined as C4::Context->needs_install is false'
210 $schema->storage->txn_rollback;
213 sub get_defined_routes {
216 traverse_routes( $_, 0, $routes ) for @{ $t->app->routes->children };
221 sub traverse_routes {
222 my ( $route, $depth, $routes ) = @_;
225 my $path = $route->pattern->unparsed || '/';
228 my $via = $route->via;
229 my $verb = !$via ? '*' : uc join ',', @$via;
230 $routes->{$path}->{$verb} = 1;
233 traverse_routes( $_, $depth, $routes ) for @{ $route->children };