diff --git a/tests/behat/behat_auth_outage.php b/tests/behat/behat_auth_outage.php index b0f30c8..0a0fc86 100644 --- a/tests/behat/behat_auth_outage.php +++ b/tests/behat/behat_auth_outage.php @@ -14,24 +14,30 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Steps definitions related to auth_outage. - * - * @package auth_outage - * @author Daniel Thee Roperto - * @copyright 2016 Catalyst IT - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. use auth_outage\dml\outagedb; use auth_outage\local\outage; +use Behat\Gherkin\Node\TableNode; use Behat\Mink\Exception\ExpectationException; require_once(__DIR__.'/../../../../lib/behat/behat_base.php'); +/** + * Steps definitions related to auth_outage. + * + * @package auth_outage + * @author Daniel Thee Roperto + * @copyright 2016 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @SuppressWarnings("public") Allow this test to have as many tests as necessary. + */ class behat_auth_outage extends behat_base { + /** + * @var outage Which outage are we checking. + */ + private $outage = null; + /** * @Given the authentication plugin :name is enabled */ @@ -159,4 +165,109 @@ class behat_auth_outage extends behat_base { throw new ExpectationException('Number of windows: '.$count, $this->getSession()); } } + + /** + * @Then I should see :text in the warning bar + */ + public function i_should_see_in_the_warning_bar($text) { + $element = '#auth_outage_warningbar_box'; + + $container = $this->getSession()->getPage()->findAll('css', $element); + if (count($container) == 0) { + throw new ExpectationException('"'.$element.'" element not found', $this->getSession()); + } + $container = $container[0]; + + $xpathliteral = behat_context_helper::escape($text); + $xpath = "/descendant-or-self::*[contains(., $xpathliteral)]". + "[count(descendant::*[contains(., $xpathliteral)]) = 0]"; + + $found = $this->find_all('xpath', $xpath, false, $container); + if (count($found) == 0) { + throw new ExpectationException('"'.$text.'" text was not found in the "'.$element.'" element', $this->getSession()); + } + + foreach ($found as $node) { + if ($node->isVisible()) { + return; + } + } + throw new ExpectationException('"'.$text.'" text was found in the "'.$element.'" element but was not visible', + $this->getSession()); + } + + /** + * @Then I should not see the warning bar + */ + public function i_should_not_see_the_warning_bar() { + $selector = 'css'; + $locator = "#auth_outage_warningbar_box"; + $items = $this->getSession()->getPage()->findAll($selector, $locator); + if (count($items) > 0) { + throw new ExpectationException($locator.' found, not expected.', $this->getSession()); + } + } + + /** + * @Given there is the following outage: + */ + public function there_is_the_following_outage(TableNode $data) { + $time = time(); + $row = $data->getHash()[0]; + + // Set defaults. + $row = array_merge( + [ + 'autostart' => 'no', + 'warnbefore' => 60, + 'startsin' => 0, + 'stopsafter' => 60, + 'finished' => null, + 'title' => 'Outage Title', + 'description' => 'Outage Description.', + ], + $row + ); + if (($row['autostart'] != 'yes') && ($row['autostart'] != 'no')) { + throw new Exception('autostart must be yes or no, found: '.$row['autostart']); + } + if ($row['finished'] == '') { + $row['finished'] = null; + } + + $starttime = $time + $row['startsin']; + $this->outage = new outage([ + 'autostart' => ($row['autostart'] == 'yes'), + 'warntime' => $starttime - $row['warnbefore'], + 'starttime' => $starttime, + 'stoptime' => $starttime + $row['stopsafter'], + 'finished' => $row['finished'], + 'title' => $row['title'], + 'description' => $row['description'], + ]); + outagedb::save($this->outage); + } + + /** + * @When /^I wait until the outage (?Pwarns|starts|stops)$/ + */ + public function i_wait_until_outage($what) { + switch ($what) { + case 'warns': + $seconds = $this->outage->warntime - time(); + break; + case 'starts': + $seconds = $this->outage->starttime - time(); + break; + case 'stops': + $seconds = $this->outage->stoptime - time(); + break; + default: + throw new Exception('Invalid $what='.$what); + } + if ($seconds >= 0) { + $seconds++; // Give one extra second for things to happen. + $this->getSession()->wait($seconds * 1000, false); + } + } } diff --git a/tests/behat/default_settings.feature b/tests/behat/default_settings.feature index ef8fa49..033db49 100644 --- a/tests/behat/default_settings.feature +++ b/tests/behat/default_settings.feature @@ -1,5 +1,5 @@ @auth @auth_outage @javascript -Feature: Test changing the default settings. +Feature: Change the default settings In order to easily create outages As an admin I need to configure the outage defaults diff --git a/tests/behat/manage_outages.feature b/tests/behat/manage_outages.feature index a85198d..0bc6365 100644 --- a/tests/behat/manage_outages.feature +++ b/tests/behat/manage_outages.feature @@ -1,8 +1,8 @@ @auth @auth_outage @javascript -Feature: Test the outage management functionality. - In order to check if I can manage outages +Feature: Manage outages + In order to manage outages As an admin - I need to view, create, edit, delete, clone and finish an outage. + I need to view, create, edit, delete, clone and finish an outage Outage stage terminology: - waiting is an outage in the future, not yet in the warning period. diff --git a/tests/behat/warningbar.feature b/tests/behat/warningbar.feature new file mode 100644 index 0000000..5542d8d --- /dev/null +++ b/tests/behat/warningbar.feature @@ -0,0 +1,56 @@ +@dev @auth @auth_outage @javascript +Feature: Warning bar + In order alert users about an outage + As any user + I need to view the warning bar + + Outage stage terminology: + - waiting is an outage in the future, not yet in the warning period. + - warning is an outage in the future but already in the warning period. + - ongoing is an outage that has started, but not yet reached the stop time nor is marked as finished. + - finished is an outage that has explicitly been marked as finished. + - stopped is an outage that has already ended but not explicitly marked as finished. + + + Background: + Given the authentication plugin "outage" is enabled + + + Scenario: This is how an outage should happend without maintenance mode and manual finish. + Given there is the following outage: + | warnbefore | startsin | stopsafter | + | 10 | 20 | 10 | + When I am on homepage + Then I should not see the warning bar + When I wait until the outage warns + And I reload the page + Then I should see "Shutting down in" in the warning bar + When I wait until the outage starts + Then I should see "Back online at" in the warning bar + When I wait until the outage stops + Then I should see "We are back online!" in the warning bar + When I reload the page + Then I should not see the warning bar + + + Scenario Outline: Some stages should show its own warning message. + Given there is a outage + When I am on homepage + Then I should see "" in the warning bar + + Examples: + | type | see | + | warning | Shutting down in | + | ongoing | Back online at | + + + Scenario Outline: Some stages should not have a warning bar. + Given there is a outage + When I am on homepage + Then I should not see the warning bar + + Examples: + | type | + | waiting | + | finished | + | stopped | diff --git a/tests/phpunit/local/controllers/infopage_test.php b/tests/phpunit/local/controllers/infopage_test.php index 5082289..cc4527d 100644 --- a/tests/phpunit/local/controllers/infopage_test.php +++ b/tests/phpunit/local/controllers/infopage_test.php @@ -17,6 +17,7 @@ use auth_outage\dml\outagedb; use auth_outage\local\controllers\infopage; use auth_outage\local\outage; +use auth_outage\task\update_static_page; defined('MOODLE_INTERNAL') || die(); @@ -272,13 +273,12 @@ class infopagecontroller_test extends advanced_testcase { 'description' => 'Description', ]); $info = new infopage(['outage' => $outage]); - self::hasExpectationOnOutput(); $output = $info->get_output(); self::assertContains('auth_outage_info', $output); } public function test_tasks() { - $task = new \auth_outage\task\update_static_page(); + $task = new update_static_page(); self::assertNotEmpty($task->get_name()); $task->execute(); } diff --git a/tests/phpunit/local/outagelib_test.php b/tests/phpunit/local/outagelib_test.php index 84dfd85..f6dd57b 100644 --- a/tests/phpunit/local/outagelib_test.php +++ b/tests/phpunit/local/outagelib_test.php @@ -86,7 +86,6 @@ class outagelib_test extends advanced_testcase { } public function test_inject_broken() { - global $CFG; $_GET = ['auth_outage_break_code' => '1']; outagelib::reinject(); self::assertCount(2, phpunit_util::get_debugging_messages()); diff --git a/views/warningbar/warningbar.js b/views/warningbar/warningbar.js index c359e4c..b8cb679 100644 --- a/views/warningbar/warningbar.js +++ b/views/warningbar/warningbar.js @@ -78,9 +78,18 @@ var auth_outage_warningbar = { xmlhttp.open("GET", this.checkfinishedurl, true); xmlhttp.send(); + var estimatedServerTime = this.servertime + (Date.now() - this.clienttime); + var sleepSeconds = this.stops - estimatedServerTime; // How long to sleep until it stops. + if (sleepSeconds <= 0) { + sleepSeconds = 5; // It should be back, keep checking every 5 seconds. + } + else { + sleepSeconds = Math.min(sleepSeconds, (5 * 60)); // Check at least every 5 minutes. + } + setTimeout(function () { $this.tickOngoing(); - }, (5 * 60 * 1000)); // Check every 5 minutes. + }, sleepSeconds * 1000); }, ajaxCheckFinished: function (ajax) { @@ -94,6 +103,7 @@ var auth_outage_warningbar = { }, finish: function () { + this.finished = true; this.divblock.className = 'auth_outage_finished_period'; if (this.finishbutton) { this.finishbutton.style.display = 'none';