Bugzilla – Attachment 183469 Details for
Bug 39522
Add hooks to allow 'Valuebuilder' plugins to be installable
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 39522: Add unit tests for valuebuilder plugin hooks
Bug-39522-Add-unit-tests-for-valuebuilder-plugin-h.patch (text/plain), 14.83 KB, created by
Martin Renvoize (ashimema)
on 2025-06-24 15:35:34 UTC
(
hide
)
Description:
Bug 39522: Add unit tests for valuebuilder plugin hooks
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2025-06-24 15:35:34 UTC
Size:
14.83 KB
patch
obsolete
>From 729fb175f47e8a7d931d1ade21444d555495c870 Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@openfifth.co.uk> >Date: Tue, 24 Jun 2025 16:33:19 +0100 >Subject: [PATCH] Bug 39522: Add unit tests for valuebuilder plugin hooks > >This patch adds comprehensive unit tests for the new valuebuilder plugin >functionality. The tests verify that plugins can provide valuebuilders >through the get_valuebuilder() method and that FrameworkPlugin can >correctly load and integrate with plugin-based valuebuilders. > >The tests use a dedicated TestValuebuilder plugin to ensure realistic >testing scenarios without relying on mocks, following the pattern >established in other plugin hook tests. > >Test plan: >1. Run the new test file: > prove t/db_dependent/Koha/Plugins/Valuebuilder_hooks.t >2. Verify all tests pass (9 tests total) >3. Run all plugin tests to ensure no regressions: > prove t/db_dependent/Koha/Plugins/ >4. Verify all plugin tests still pass (113 tests across 19 files) >5. Test the specific functionality: > - Verify plugins without get_valuebuilder() method are not found as valuebuilders > - Verify plugins with get_valuebuilder() method are correctly discovered > - Verify FrameworkPlugin can load plugin-based valuebuilders > - Verify JavaScript generation works with plugin valuebuilders > - Verify plugin enable/disable affects valuebuilder availability >6. Confirm FrameworkPlugin integration tests still pass: > prove t/db_dependent/FrameworkPlugin.t >--- > .../Koha/Plugins/Valuebuilder_hooks.t | 203 ++++++++++++++++++ > t/lib/plugins/Koha/Plugin/TestValuebuilder.pm | 80 +++++++ > .../test_valuebuilder_popup.tt | 29 +++ > 3 files changed, 312 insertions(+) > create mode 100644 t/db_dependent/Koha/Plugins/Valuebuilder_hooks.t > create mode 100644 t/lib/plugins/Koha/Plugin/TestValuebuilder.pm > create mode 100644 t/lib/plugins/Koha/Plugin/TestValuebuilder/test_valuebuilder_popup.tt > >diff --git a/t/db_dependent/Koha/Plugins/Valuebuilder_hooks.t b/t/db_dependent/Koha/Plugins/Valuebuilder_hooks.t >new file mode 100644 >index 00000000000..5afebaae418 >--- /dev/null >+++ b/t/db_dependent/Koha/Plugins/Valuebuilder_hooks.t >@@ -0,0 +1,203 @@ >+#!/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::NoWarnings; >+use Test::More tests => 9; >+ >+use File::Basename; >+ >+use C4::Context; >+ >+use Koha::FrameworkPlugin; >+ >+use t::lib::Mocks; >+use t::lib::TestBuilder; >+ >+BEGIN { >+ # Mock pluginsdir before loading Plugins module >+ my $path = dirname(__FILE__) . '/../../../lib/plugins'; >+ t::lib::Mocks::mock_config( 'pluginsdir', $path ); >+ >+ use_ok('Koha::Plugins'); >+ use_ok('Koha::Plugins::Handler'); >+ use_ok('Koha::Plugin::Test'); >+ use_ok('Koha::Plugin::TestValuebuilder'); >+} >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+t::lib::Mocks::mock_config( 'enable_plugins', 1 ); >+ >+subtest 'get_valuebuilders_installed() tests' => sub { >+ >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ # Temporarily remove any installed plugins data >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ >+ my $plugins = Koha::Plugins->new; >+ $plugins->InstallPlugins; >+ >+ # Test 1: No valuebuilders when no plugins have get_valuebuilder method >+ # Only enable the regular Test plugin (which doesn't have get_valuebuilder) >+ my $regular_plugin = Koha::Plugin::Test->new->enable; >+ my @valuebuilders = $plugins->get_valuebuilders_installed(); >+ is( scalar @valuebuilders, 0, 'No valuebuilders when enabled plugin lacks get_valuebuilder method' ); >+ >+ # Test 2: Enable the TestValuebuilder plugin which provides a valuebuilder >+ my $valuebuilder_plugin = Koha::Plugin::TestValuebuilder->new->enable; >+ @valuebuilders = $plugins->get_valuebuilders_installed(); >+ is( scalar @valuebuilders, 1, 'One valuebuilder found when TestValuebuilder plugin is enabled' ); >+ >+ # Test 3: Check the structure of returned valuebuilder >+ my $valuebuilder = $valuebuilders[0]; >+ is( ref($valuebuilder), 'HASH', 'Valuebuilder is returned as hashref' ); >+ is( $valuebuilder->{name}, 'test_plugin_valuebuilder.pl', 'Valuebuilder name matches TestValuebuilder plugin' ); >+ isa_ok( $valuebuilder->{plugin}, 'Koha::Plugin::TestValuebuilder', 'Valuebuilder plugin is correct object type' ); >+ >+ # Test 4: Disable the valuebuilder plugin and verify it's not found >+ $valuebuilder_plugin->disable; >+ @valuebuilders = $plugins->get_valuebuilders_installed(); >+ is( scalar @valuebuilders, 0, 'No valuebuilders when TestValuebuilder plugin is disabled' ); >+ >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'FrameworkPlugin valuebuilder integration tests' => sub { >+ >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ # Temporarily remove any installed plugins data >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ >+ my $plugins = Koha::Plugins->new; >+ $plugins->InstallPlugins; >+ >+ # Enable the TestValuebuilder plugin >+ my $valuebuilder_plugin = Koha::Plugin::TestValuebuilder->new->enable; >+ my $test_valuebuilder_name = $valuebuilder_plugin->get_valuebuilder(); >+ >+ # Test 1: FrameworkPlugin can find plugin-based valuebuilder >+ my $framework_plugin = Koha::FrameworkPlugin->new({ name => $test_valuebuilder_name }); >+ ok( $framework_plugin, 'FrameworkPlugin object created successfully' ); >+ is( $framework_plugin->name, $test_valuebuilder_name, 'FrameworkPlugin has correct name' ); >+ >+ # Test 2: FrameworkPlugin can load plugin-based valuebuilder >+ my $build_result = $framework_plugin->build({ id => 'test_field_001' }); >+ ok( $build_result, 'FrameworkPlugin build method succeeds with plugin valuebuilder' ); >+ >+ # Test 3: FrameworkPlugin generates javascript from plugin >+ my $javascript = $framework_plugin->javascript; >+ ok( $javascript, 'FrameworkPlugin generates javascript' ); >+ like( $javascript, qr/test_focus_test_field_001/, 'Generated javascript contains expected field-specific function' ); >+ >+ # Test 4: FrameworkPlugin can launch plugin-based valuebuilder (would need CGI mock for full test) >+ ok( $framework_plugin->{launcher}, 'FrameworkPlugin has launcher method loaded from plugin' ); >+ >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'Plugin Base valuebuilder methods tests' => sub { >+ >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ # Temporarily remove any installed plugins data >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ >+ my $plugins = Koha::Plugins->new; >+ $plugins->InstallPlugins; >+ >+ # Test 1: get_valuebuilders() with plugin that doesn't have get_valuebuilder method >+ my $regular_plugin = Koha::Plugin::Test->new->enable; >+ my $valuebuilders = $regular_plugin->get_valuebuilders(); >+ is( ref($valuebuilders), 'ARRAY', 'get_valuebuilders returns array reference' ); >+ is( scalar @$valuebuilders, 0, 'get_valuebuilders returns empty array when plugin lacks get_valuebuilder method' ); >+ >+ # Test 2: get_valuebuilders() with plugin that has get_valuebuilder method >+ my $valuebuilder_plugin = Koha::Plugin::TestValuebuilder->new->enable; >+ $valuebuilders = $valuebuilder_plugin->get_valuebuilders(); >+ is( scalar @$valuebuilders, 1, 'get_valuebuilders returns one item when plugin has get_valuebuilder method' ); >+ is( $valuebuilders->[0], 'test_plugin_valuebuilder.pl', 'get_valuebuilders returns correct valuebuilder name' ); >+ >+ # Test 3: get_valuebuilder_url() method >+ my $url = $valuebuilder_plugin->get_valuebuilder_url(); >+ my $expected_class = ref($valuebuilder_plugin); >+ like( $url, qr|/cgi-bin/koha/plugins/run\.pl\?class=$expected_class&method=launcher|, >+ 'get_valuebuilder_url returns correct URL format' ); >+ >+ # Test 4: get_valuebuilder() method directly >+ my $valuebuilder_name = $valuebuilder_plugin->get_valuebuilder(); >+ is( $valuebuilder_name, 'test_plugin_valuebuilder.pl', 'get_valuebuilder returns expected name' ); >+ >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'Real FrameworkPlugin integration with valuebuilder plugins' => sub { >+ >+ plan tests => 12; >+ >+ $schema->storage->txn_begin; >+ >+ # Temporarily remove any installed plugins data >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ >+ my $plugins = Koha::Plugins->new; >+ $plugins->InstallPlugins; >+ >+ # Enable our test valuebuilder plugin >+ my $valuebuilder_plugin = Koha::Plugin::TestValuebuilder->new->enable; >+ ok( $valuebuilder_plugin->is_enabled, 'TestValuebuilder plugin is enabled' ); >+ >+ # Test 1: Verify the plugin provides a valuebuilder >+ my $valuebuilder_name = $valuebuilder_plugin->get_valuebuilder(); >+ is( $valuebuilder_name, 'test_plugin_valuebuilder.pl', 'TestValuebuilder plugin returns correct valuebuilder name' ); >+ >+ # Test 2: Verify get_valuebuilders_installed finds our plugin >+ my @valuebuilders = $plugins->get_valuebuilders_installed(); >+ is( scalar @valuebuilders, 1, 'get_valuebuilders_installed finds one valuebuilder' ); >+ is( $valuebuilders[0]->{name}, $valuebuilder_name, 'Found valuebuilder has correct name' ); >+ isa_ok( $valuebuilders[0]->{plugin}, 'Koha::Plugin::TestValuebuilder', 'Found valuebuilder has correct plugin type' ); >+ >+ # Test 3: FrameworkPlugin can load our plugin-based valuebuilder >+ my $framework_plugin = Koha::FrameworkPlugin->new({ name => $valuebuilder_name }); >+ ok( $framework_plugin, 'FrameworkPlugin created successfully with plugin valuebuilder name' ); >+ is( $framework_plugin->name, $valuebuilder_name, 'FrameworkPlugin has correct name' ); >+ ok( !$framework_plugin->errstr, 'FrameworkPlugin has no errors' ); >+ >+ # Test 4: FrameworkPlugin can build JavaScript from our plugin >+ my $build_result = $framework_plugin->build({ id => 'test_field_123' }); >+ ok( $build_result, 'FrameworkPlugin build succeeds with real plugin valuebuilder' ); >+ >+ my $javascript = $framework_plugin->javascript; >+ ok( $javascript, 'FrameworkPlugin generates JavaScript from plugin' ); >+ like( $javascript, qr/test_focus_test_field_123/, 'Generated JavaScript contains expected function for field ID' ); >+ like( $javascript, qr/test_click_test_field_123/, 'Generated JavaScript contains expected click function for field ID' ); >+ >+ Koha::Plugins->RemovePlugins( { destructive => 1 } ); >+ $schema->storage->txn_rollback; >+}; >\ No newline at end of file >diff --git a/t/lib/plugins/Koha/Plugin/TestValuebuilder.pm b/t/lib/plugins/Koha/Plugin/TestValuebuilder.pm >new file mode 100644 >index 00000000000..28664007e54 >--- /dev/null >+++ b/t/lib/plugins/Koha/Plugin/TestValuebuilder.pm >@@ -0,0 +1,80 @@ >+package Koha::Plugin::TestValuebuilder; >+ >+## It's good practice to use Modern::Perl >+use Modern::Perl; >+ >+## Required for all plugins >+use base qw(Koha::Plugins::Base); >+ >+our $VERSION = "v1.01"; >+our $metadata = { >+ name => 'Test Valuebuilder Plugin', >+ author => 'Koha Development Team', >+ description => 'Test plugin for valuebuilder functionality', >+ date_authored => '2025-01-01', >+ date_updated => '2025-01-01', >+ minimum_version => '3.11', >+ maximum_version => undef, >+ version => $VERSION, >+ namespace => 'test_valuebuilder', >+ valuebuilder_tag => 'valuebuilder_test', >+}; >+ >+## This is the minimum code required for a plugin's 'new' method >+## More can be added, but none should be removed >+sub new { >+ my ( $class, $args ) = @_; >+ $args->{'metadata'} = $metadata; >+ my $self = $class->SUPER::new($args); >+ return $self; >+} >+ >+## This method returns the name of the valuebuilder this plugin provides >+sub get_valuebuilder { >+ my $self = shift; >+ return 'test_plugin_valuebuilder.pl'; >+} >+ >+## This method provides the builder code (JavaScript) for the valuebuilder >+sub builder_code { >+ my ( $self, $params ) = @_; >+ >+ my $id = $params->{id} || 'default_id'; >+ >+ return qq{ >+ <script> >+ function test_focus_$id() { >+ var field = document.getElementById('$id'); >+ if (field && field.value === '') { >+ field.value = 'Plugin Generated Value'; >+ } >+ } >+ >+ function test_click_$id() { >+ window.open('/cgi-bin/koha/plugins/run.pl?class=Koha::Plugin::TestValuebuilder&method=launcher&id=$id', >+ 'valuebuilder', >+ 'width=500,height=400,toolbar=false,scrollbars=yes'); >+ } >+ </script> >+ }; >+} >+ >+## This method provides the launcher (popup) functionality for the valuebuilder >+sub launcher { >+ my ( $self, $params ) = @_; >+ >+ my $input = $self->{cgi}; >+ my $id = $input->param('id') || 'default_id'; >+ >+ my $template = $self->get_template({ file => 'test_valuebuilder_popup.tt' }); >+ >+ $template->param( >+ field_id => $id, >+ plugin_name => 'Test Valuebuilder Plugin', >+ ); >+ >+ print $input->header(); >+ print $template->output(); >+} >+ >+1; >\ No newline at end of file >diff --git a/t/lib/plugins/Koha/Plugin/TestValuebuilder/test_valuebuilder_popup.tt b/t/lib/plugins/Koha/Plugin/TestValuebuilder/test_valuebuilder_popup.tt >new file mode 100644 >index 00000000000..cd0eed1a688 >--- /dev/null >+++ b/t/lib/plugins/Koha/Plugin/TestValuebuilder/test_valuebuilder_popup.tt >@@ -0,0 +1,29 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <title>[% plugin_name %] - Valuebuilder</title> >+ <meta charset="UTF-8"> >+</head> >+<body> >+ <h1>[% plugin_name %]</h1> >+ <p>This is a test valuebuilder popup for field: [% field_id %]</p> >+ >+ <form> >+ <label for="test_value">Enter a value:</label> >+ <input type="text" id="test_value" value="Test Value from Plugin"> >+ <br><br> >+ <button type="button" onclick="setValueAndClose()">Set Value</button> >+ <button type="button" onclick="window.close()">Cancel</button> >+ </form> >+ >+ <script> >+ function setValueAndClose() { >+ var value = document.getElementById('test_value').value; >+ if (window.opener && window.opener.document.getElementById('[% field_id %]')) { >+ window.opener.document.getElementById('[% field_id %]').value = value; >+ } >+ window.close(); >+ } >+ </script> >+</body> >+</html> >\ No newline at end of file >-- >2.49.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 39522
:
180283
|
180284
|
180301
|
180302
|
180337
|
180338
|
183467
|
183468
| 183469