@@ -, +, @@ --- t/db_dependent/selenium/authenticate.t | 166 ----------------------- t/db_dependent/selenium/authentication.t | 131 ++++++++++++++++++ t/lib/Selenium.pm | 17 ++- 3 files changed, 147 insertions(+), 167 deletions(-) delete mode 100644 t/db_dependent/selenium/authenticate.t create mode 100644 t/db_dependent/selenium/authentication.t --- a/t/db_dependent/selenium/authenticate.t +++ a/t/db_dependent/selenium/authenticate.t @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -# This file is part of Koha. -# -# Copyright (C) 2017 Catalyst IT -# -# 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 . - -#This selenium test is to test authentication, by performing the following: create a category and patron (same as basic_workflow.t). Then the superlibrarian logs out and the created patron must log into the staff intranet and OPAC - -#Note: If you are testing this on kohadevbox with selenium installed in kohadevbox then you need to set the staffClientBaseURL to localhost:8080 and the OPACBaseURL to localhost:80 - -use Modern::Perl; - -use Time::HiRes qw(gettimeofday); -use C4::Context; -use C4::Biblio qw( AddBiblio ); # We shouldn't use it - -use Test::More tests => 9; -use MARC::Record; -use MARC::Field; - -my $dbh = C4::Context->dbh; -my $login = $ENV{KOHA_USER} || 'koha'; -my $password = $ENV{KOHA_PASS} || 'koha'; -my $staff_client_base_url = - $ENV{KOHA_INTRANET_URL} || C4::Context->preference("staffClientBaseUrl") || q{}; -my $base_url= $staff_client_base_url . "/cgi-bin/koha/"; -my $opac_url = $ENV{KOHA_OPAC_URL} || C4::Context->preference("OPACBaseURL") || q{}; - - -our $sample_data = { - category => { - categorycode => 'test_cat', - description => 'test cat description', - enrolmentperiod => '12', - category_type => 'A' - }, - patron => { - surname => 'test_patron_surname', - cardnumber => '4242424242', - userid => 'test_username', - password => 'Password123', - password2 => 'Password123' - }, -}; - -my $patronusername="test_username"; -my $patronpassword="password"; - -our ( $borrowernumber, $start, $prev_time, $cleanup_needed ); - -SKIP: { - eval { require Selenium::Remote::Driver; }; - skip "Selenium::Remote::Driver is needed for selenium tests.", 20 if $@; - - $cleanup_needed = 1; - - open my $fh, '>>', '/tmp/output.txt'; - - my $driver = Selenium::Remote::Driver->new; - $start = gettimeofday; - $prev_time = $start; - $driver->get($base_url."mainpage.pl"); - like( $driver->get_title(), qr(Log in to Koha), ); - auth( $driver, $login, $password ); - time_diff("main"); - - $driver->get($base_url.'admin/categories.pl'); - like( $driver->get_title(), qr(Patron categories), ); - $driver->find_element('//a[@id="newcategory"]')->click; - like( $driver->get_title(), qr(New category), ); - fill_form( $driver, $sample_data->{category} ); - $driver->find_element('//fieldset[@class="action"]/input[@type="submit"]')->click; - - time_diff("add patron category"); - $driver->get($base_url.'/members/memberentry.pl?op=add&categorycode='.$sample_data->{category}{categorycode}); - like( $driver->get_title(), qr(Add .*$sample_data->{category}{description}), ); - fill_form( $driver, $sample_data->{patron} ); - $driver->find_element('//button[@id="saverecord"]')->click; - like( $driver->get_title(), qr(Patron details for $sample_data->{patron}{surname}), ); - time_diff("add patron"); - - $driver->get($base_url.'/mainpage.pl?logout.x=1'); - like( $driver->get_title(), qr(Log in to Koha), ); - time_diff("Logout"); - - $driver->get($base_url."mainpage.pl"); - like( $driver->get_title(), qr(Log in to Koha), ); - patron_auth( $driver, $sample_data->{patron} ); - time_diff("New patron logs into intranet"); - - $driver->get($base_url.'/mainpage.pl?logout.x=1'); - like( $driver->get_title(), qr(Log in to Koha), ); - time_diff("Logout of new patron from staff intranet"); - - $driver->get($opac_url); - like( $driver->get_title(), qr(Koha online catalog), ); - patron_opac_auth( $driver, $sample_data->{patron} ); - time_diff("New patron logs into OPAC"); - - close $fh; - $driver->quit(); -}; - -END { - cleanup() if $cleanup_needed; -}; - -sub auth { - my ( $driver, $login, $password) = @_; - fill_form( $driver, { userid => $login, password => $password } ); - my $login_button = $driver->find_element('//input[@id="submit"]'); - $login_button->submit(); -} - -sub patron_auth { - my ( $driver,$patronusername, $patronpassword) = @_; - fill_form( $driver, { userid => $patronusername, password => $patronpassword } ); - my $login_button = $driver->find_element('//input[@id="submit"]'); - $login_button->submit(); -} - -sub patron_opac_auth { - my ( $driver,$patronusername, $patronpassword) = @_; - fill_form( $driver, { userid => $patronusername, password => $patronpassword } ); - my $login_button = $driver->find_element('//input[@value="Log in"]'); - $login_button->submit(); -} - -sub fill_form { - my ( $driver, $values ) = @_; - while ( my ( $id, $value ) = each %$values ) { - my $element = $driver->find_element('//*[@id="'.$id.'"]'); - my $tag = $element->get_tag_name(); - if ( $tag eq 'input' ) { - $driver->find_element('//input[@id="'.$id.'"]')->send_keys($value); - } elsif ( $tag eq 'select' ) { - $driver->find_element('//select[@id="'.$id.'"]/option[@value="'.$value.'"]')->click; - } - } -} - -sub cleanup { - my $dbh = C4::Context->dbh; - $dbh->do(q|DELETE FROM categories WHERE categorycode = ?|, {}, $sample_data->{category}{categorycode}); - $dbh->do(q|DELETE FROM borrowers WHERE userid = ?|, {}, $sample_data->{patron}{userid}); -} - -sub time_diff { - my $lib = shift; - my $now = gettimeofday; - warn "CP $lib = " . sprintf("%.2f", $now - $prev_time ) . "\n"; - $prev_time = $now; -} --- a/t/db_dependent/selenium/authentication.t +++ a/t/db_dependent/selenium/authentication.t @@ -0,0 +1,131 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Copyright (C) 2017 Catalyst IT +# Copyright 2018 Koha Development team +# +# 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 . + +#This selenium test is to test authentication, by performing the following: create a category and patron (same as basic_workflow.t). Then the superlibrarian logs out and the created patron must log into the staff intranet and OPAC + +#Note: If you are testing this on kohadevbox with selenium installed in kohadevbox then you need to set the staffClientBaseURL to localhost:8080 and the OPACBaseURL to localhost:80 + +use Modern::Perl; +use Test::More tests => 2; + +use C4::Context; +use Koha::AuthUtils; +use t::lib::Selenium; +use t::lib::TestBuilder; + +my @data_to_cleanup; + +SKIP: { + eval { require Selenium::Remote::Driver; }; + skip "Selenium::Remote::Driver is needed for selenium tests.", 2 if $@; + + my $builder = t::lib::TestBuilder->new; + my $s = t::lib::Selenium->new; + my $driver = $s->driver; + + subtest 'Staff interface authentication' => sub { + plan tests => 5; + my $mainpage = $s->base_url . q|mainpage.pl|; + $driver->get($mainpage); + like( $driver->get_title, qr(Log in to Koha), 'Hitting the main page should redirect to the login form'); + + my $password = Koha::AuthUtils::generate_password(); + my $digest = Koha::AuthUtils::hash_password( $password ); + my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => 0 }}); + $patron->update_password( $patron->userid, $digest ); + + # Patron does not have permission to access staff interface + $s->auth( $patron->userid, $password ); + like( $driver->get_title, qr(Access denied), 'Patron without permission should be redirected to the login form' ); + + $driver->get($mainpage . q|?logout.x=1|); + $patron->flags(4)->store; # catalogue permission + $s->auth( $patron->userid, $password ); + like( $driver->get_title, qr(Koha staff client), 'Patron with flags catalogue should be able to login' ); + + $driver->get($mainpage . q|?logout.x=1|); + like( $driver->get_title(), qr(Log in to Koha), 'If logout is requested, login form should be displayed' ); + + $patron->flags(1)->store; # superlibrarian permission + $s->auth( $patron->userid, $password ); + like( $driver->get_title, qr(Koha staff client), 'Patron with flags superlibrarian should be able to login' ); + }; + + subtest 'OPAC interface authentication' => sub { + plan tests => 6; + + my $mainpage = $s->opac_base_url . q|opac-main.pl|; + $driver->get($mainpage); + like( $driver->get_title, qr(Koha online catalog), 'Hitting the main page should not redirect to the login form'); + + my $password = Koha::AuthUtils::generate_password(); + my $digest = Koha::AuthUtils::hash_password( $password ); + my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => 0 }}); + $patron->update_password( $patron->userid, $digest ); + + # Using the modal + $driver->find_element('//a[@class="login-link loginModal-trigger"]')->click; + $s->fill_form( { muserid => $patron->userid, mpassword => $password } ); + $driver->find_element('//div[@id="loginModal"]//input[@type="submit"]')->click; + like( $driver->get_title, qr(Koha online catalog), 'Patron without permission should be able to login to the OPAC using the modal' ); + $driver->find_element('//div[@id="userdetails"]'); + like( $driver->get_title, qr(Your library home), 'Patron without permissions should be able to login to the OPAC using the modal'); + + $driver->find_element('//a[@id="logout"]')->click; + $driver->capture_screenshot('1.png'); + $driver->find_element('//div[@id="login"]'); # logged out + + # Using the form on the right + $s->fill_form( { userid => $patron->userid, password => $password } ); + $s->submit_form; + $driver->find_element('//div[@id="userdetails"]'); + like( $driver->get_title, qr(Your library home), 'Patron without permissions should be able to login to the OPAC using the form on the right'); + + $driver->find_element('//a[@id="logout"]')->click; + $driver->find_element('//div[@id="login"]'); # logged out + + + $patron->flags(4)->store; # catalogue permission + $s->fill_form( { userid => $patron->userid, password => $password } ); + $s->submit_form; + $driver->find_element('//div[@id="userdetails"]'); + like( $driver->get_title, qr(Your library home), 'Patron with catalogue permission should be able to login to the OPAC'); + + $driver->find_element('//a[@id="logout"]')->click; + $driver->find_element('//div[@id="login"]'); # logged out + + $patron->flags(1)->store; # superlibrarian permission + $s->fill_form( { userid => $patron->userid, password => $password } ); + $s->submit_form; + $driver->find_element('//div[@id="userdetails"]'); + like( $driver->get_title, qr(Your library home), 'Patron with superlibrarian permission should be able to login to the OPAC'); + + $driver->find_element('//a[@id="logout"]')->click; + $driver->find_element('//div[@id="login"]'); # logged out + + push @data_to_cleanup, $patron, $patron->category, $patron->library; + }; + + $driver->quit(); +}; + +END { + $_->delete for @data_to_cleanup; +}; --- a/t/lib/Selenium.pm +++ a/t/lib/Selenium.pm @@ -22,7 +22,7 @@ use Carp qw( croak ); use C4::Context; use base qw(Class::Accessor); -__PACKAGE__->mk_accessors(qw(login password base_url selenium_addr selenium_port driver)); +__PACKAGE__->mk_accessors(qw(login password base_url opac_base_url selenium_addr selenium_port driver)); sub new { my ( $class, $params ) = @_; @@ -31,6 +31,7 @@ sub new { $self->{login} = $params->{login} || $config->{login}; $self->{password} = $params->{password} || $config->{password}; $self->{base_url} = $params->{base_url} || $config->{base_url}; + $self->{opac_base_url} = $params->{opac_base_url} || $config->{opac_base_url}; $self->{selenium_addr} = $params->{selenium_addr} || $config->{selenium_addr}; $self->{selenium_port} = $params->{selenium_port} || $config->{selenium_port}; $self->{driver} = Selenium::Remote::Driver->new( @@ -54,6 +55,7 @@ sub config { login => $ENV{KOHA_USER} || 'koha', password => $ENV{KOHA_PASS} || 'koha', base_url => ( $ENV{KOHA_INTRANET_URL} || C4::Context->preference("staffClientBaseURL") ) . "/cgi-bin/koha/", + opac_base_url => ( $ENV{KOHA_OPAC_URL} || C4::Context->preference("OPACBaseURL") ) . "/cgi-bin/koha/", selenium_addr => $ENV{SELENIUM_ADDR} || 'localhost', selenium_port => $ENV{SELENIUM_PORT} || 4444, }; @@ -72,6 +74,19 @@ sub auth { $login_button->submit(); } +sub opac_auth { + my ( $self, $login, $password ) = @_; + + $login ||= $self->login; + $password ||= $self->password; + my $mainpage = $self->base_url . 'opac-main.pl'; + + $self->driver->get($mainpage); + $self->fill_form( { userid => $login, password => $password } ); + my $login_button = $self->driver->find_element('//input[@id="submit"]'); + $login_button->submit(); +} + sub fill_form { my ( $self, $values ) = @_; while ( my ( $id, $value ) = each %$values ) { --