You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1112 lines
32 KiB
1112 lines
32 KiB
2 years ago
|
<?php
|
||
|
// This file is part of Moodle - http://moodle.org/
|
||
|
//
|
||
|
// Moodle 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.
|
||
|
//
|
||
|
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
/**
|
||
|
* Tests for tour.
|
||
|
*
|
||
|
* @package tool_usertours
|
||
|
* @copyright 2016 Andrew Nicols <andrew@nicols.co.uk>
|
||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||
|
*/
|
||
|
|
||
|
defined('MOODLE_INTERNAL') || die();
|
||
|
|
||
|
global $CFG;
|
||
|
require_once($CFG->libdir . '/formslib.php');
|
||
|
|
||
|
use tool_usertours\tour;
|
||
|
|
||
|
/**
|
||
|
* Tests for tour.
|
||
|
*
|
||
|
* @package tool_usertours
|
||
|
* @copyright 2016 Andrew Nicols <andrew@nicols.co.uk>
|
||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||
|
*/
|
||
|
class tour_testcase extends advanced_testcase {
|
||
|
|
||
|
/**
|
||
|
* @var moodle_database
|
||
|
*/
|
||
|
protected $db;
|
||
|
|
||
|
/**
|
||
|
* Setup to store the DB reference.
|
||
|
*/
|
||
|
public function setUp() {
|
||
|
global $DB;
|
||
|
|
||
|
$this->db = $DB;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Tear down to restore the original DB reference.
|
||
|
*/
|
||
|
public function tearDown() {
|
||
|
global $DB;
|
||
|
|
||
|
$DB = $this->db;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Helper to mock the database.
|
||
|
*
|
||
|
* @return moodle_database
|
||
|
*/
|
||
|
public function mock_database() {
|
||
|
global $DB;
|
||
|
|
||
|
$DB = $this->getMockBuilder(\moodle_database::class)
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
return $DB;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Data provider for the dirty value tester.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function dirty_value_provider() {
|
||
|
return [
|
||
|
'name' => [
|
||
|
'name',
|
||
|
['Lorem'],
|
||
|
],
|
||
|
'description' => [
|
||
|
'description',
|
||
|
['Lorem'],
|
||
|
],
|
||
|
'pathmatch' => [
|
||
|
'pathmatch',
|
||
|
['Lorem'],
|
||
|
],
|
||
|
'enabled' => [
|
||
|
'enabled',
|
||
|
['Lorem'],
|
||
|
],
|
||
|
'sortorder' => [
|
||
|
'sortorder',
|
||
|
[1],
|
||
|
],
|
||
|
'config' => [
|
||
|
'config',
|
||
|
['key', 'value'],
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test that setters mark things as dirty.
|
||
|
*
|
||
|
* @dataProvider dirty_value_provider
|
||
|
* @param string $name The name of the key being tested
|
||
|
* @param mixed $value The value being set
|
||
|
*/
|
||
|
public function test_dirty_values($name, $value) {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
$method = 'set_' . $name;
|
||
|
call_user_func_array([$tour, $method], $value);
|
||
|
|
||
|
$rc = new \ReflectionClass(\tool_usertours\tour::class);
|
||
|
$rcp = $rc->getProperty('dirty');
|
||
|
$rcp->setAccessible(true);
|
||
|
|
||
|
$this->assertTrue($rcp->getValue($tour));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Data provider for the get_ tests.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getter_provider() {
|
||
|
return [
|
||
|
'id' => [
|
||
|
'id',
|
||
|
rand(1, 100),
|
||
|
],
|
||
|
'name' => [
|
||
|
'name',
|
||
|
'Lorem',
|
||
|
],
|
||
|
'description' => [
|
||
|
'description',
|
||
|
'Lorem',
|
||
|
],
|
||
|
'pathmatch' => [
|
||
|
'pathmatch',
|
||
|
'Lorem',
|
||
|
],
|
||
|
'enabled' => [
|
||
|
'enabled',
|
||
|
'Lorem',
|
||
|
],
|
||
|
'sortorder' => [
|
||
|
'sortorder',
|
||
|
rand(1, 100),
|
||
|
],
|
||
|
'config' => [
|
||
|
'config',
|
||
|
['key', 'value'],
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test that getters return the configured value.
|
||
|
*
|
||
|
* @dataProvider getter_provider
|
||
|
* @param string $key The name of the key being tested
|
||
|
* @param mixed $value The value being set
|
||
|
*/
|
||
|
public function test_getters($key, $value) {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
|
||
|
$rcp = $rc->getProperty($key);
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, $value);
|
||
|
|
||
|
$getter = 'get_' . $key;
|
||
|
|
||
|
$this->assertEquals($value, $tour->$getter());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ensure that non-dirty tours are not persisted.
|
||
|
*/
|
||
|
public function test_persist_non_dirty() {
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods(['to_record'])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->never())
|
||
|
->method('to_record')
|
||
|
;
|
||
|
|
||
|
$this->assertSame($tour, $tour->persist());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ensure that new dirty tours are persisted.
|
||
|
*/
|
||
|
public function test_persist_dirty_new() {
|
||
|
// Mock the database.
|
||
|
$DB = $this->mock_database();
|
||
|
|
||
|
$DB->expects($this->never())
|
||
|
->method('update_record')
|
||
|
;
|
||
|
|
||
|
$id = rand(1, 100);
|
||
|
$DB->expects($this->once())
|
||
|
->method('insert_record')
|
||
|
->willReturn($id)
|
||
|
;
|
||
|
|
||
|
// Mock the tour.
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'to_record',
|
||
|
'reload',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('to_record')
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('reload')
|
||
|
;
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
|
||
|
$rcp = $rc->getProperty('dirty');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, true);
|
||
|
|
||
|
$this->assertSame($tour, $tour->persist());
|
||
|
|
||
|
$rcp = $rc->getProperty('id');
|
||
|
$rcp->setAccessible(true);
|
||
|
$this->assertEquals($id, $rcp->getValue($tour));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ensure that non-dirty, forced tours are persisted.
|
||
|
*/
|
||
|
public function test_persist_force_new() {
|
||
|
global $DB;
|
||
|
|
||
|
// Mock the database.
|
||
|
$DB = $this->mock_database();
|
||
|
|
||
|
$DB->expects($this->never())
|
||
|
->method('update_record')
|
||
|
;
|
||
|
|
||
|
$id = rand(1, 100);
|
||
|
$DB->expects($this->once())
|
||
|
->method('insert_record')
|
||
|
->willReturn($id)
|
||
|
;
|
||
|
|
||
|
// Mock the tour.
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'to_record',
|
||
|
'reload',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('to_record')
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('reload')
|
||
|
;
|
||
|
|
||
|
$this->assertSame($tour, $tour->persist(true));
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('id');
|
||
|
$rcp->setAccessible(true);
|
||
|
$this->assertEquals($id, $rcp->getValue($tour));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ensure that dirty tours are persisted.
|
||
|
*/
|
||
|
public function test_persist_dirty_existing() {
|
||
|
// Mock the database.
|
||
|
$DB = $this->mock_database();
|
||
|
$DB->expects($this->once())
|
||
|
->method('update_record')
|
||
|
->willReturn($this->returnSelf())
|
||
|
;
|
||
|
|
||
|
$DB->expects($this->never())
|
||
|
->method('insert_record')
|
||
|
;
|
||
|
|
||
|
// Mock the tour.
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'to_record',
|
||
|
'reload',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('to_record')
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('reload')
|
||
|
;
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
|
||
|
$rcp = $rc->getProperty('id');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, 42);
|
||
|
|
||
|
$rcp = $rc->getProperty('dirty');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, true);
|
||
|
|
||
|
$this->assertSame($tour, $tour->persist());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ensure that non-dirty, forced tours are persisted.
|
||
|
*/
|
||
|
public function test_persist_force() {
|
||
|
global $DB;
|
||
|
|
||
|
// Mock the database.
|
||
|
$DB = $this->mock_database();
|
||
|
|
||
|
$DB->expects($this->once())
|
||
|
->method('update_record')
|
||
|
->willReturn($this->returnSelf())
|
||
|
;
|
||
|
|
||
|
$DB->expects($this->never())
|
||
|
->method('insert_record')
|
||
|
;
|
||
|
|
||
|
// Mock the tour.
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'to_record',
|
||
|
'reload',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('to_record')
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('reload')
|
||
|
;
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
|
||
|
$rcp = $rc->getProperty('id');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, 42);
|
||
|
|
||
|
$rcp = $rc->getProperty('dirty');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, true);
|
||
|
|
||
|
$this->assertSame($tour, $tour->persist(true));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test setting config.
|
||
|
*/
|
||
|
public function test_set_config() {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$tour->set_config('key', 'value');
|
||
|
$tour->set_config('another', [
|
||
|
'foo' => 'bar',
|
||
|
]);
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('config');
|
||
|
$rcp->setAccessible(true);
|
||
|
$this->assertEquals((object) [
|
||
|
'key' => 'value',
|
||
|
'another' => [
|
||
|
'foo' => 'bar',
|
||
|
],
|
||
|
], $rcp->getValue($tour));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test get_config with no keys provided.
|
||
|
*/
|
||
|
public function test_get_config_no_keys() {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('config');
|
||
|
$rcp->setAccessible(true);
|
||
|
|
||
|
$allvalues = (object) [
|
||
|
'some' => 'value',
|
||
|
'another' => 42,
|
||
|
'key' => [
|
||
|
'somethingelse',
|
||
|
],
|
||
|
];
|
||
|
|
||
|
$rcp->setValue($tour, $allvalues);
|
||
|
|
||
|
$this->assertEquals($allvalues, $tour->get_config());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Data provider for get_config.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function get_config_provider() {
|
||
|
$allvalues = (object) [
|
||
|
'some' => 'value',
|
||
|
'another' => 42,
|
||
|
'key' => [
|
||
|
'somethingelse',
|
||
|
],
|
||
|
];
|
||
|
|
||
|
return [
|
||
|
'No nitial config' => [
|
||
|
null,
|
||
|
null,
|
||
|
null,
|
||
|
(object) [],
|
||
|
],
|
||
|
'All values' => [
|
||
|
$allvalues,
|
||
|
null,
|
||
|
null,
|
||
|
$allvalues,
|
||
|
],
|
||
|
'Valid string value' => [
|
||
|
$allvalues,
|
||
|
'some',
|
||
|
null,
|
||
|
'value',
|
||
|
],
|
||
|
'Valid array value' => [
|
||
|
$allvalues,
|
||
|
'key',
|
||
|
null,
|
||
|
['somethingelse'],
|
||
|
],
|
||
|
'Invalid value' => [
|
||
|
$allvalues,
|
||
|
'notavalue',
|
||
|
null,
|
||
|
null,
|
||
|
],
|
||
|
'Configuration value' => [
|
||
|
$allvalues,
|
||
|
'placement',
|
||
|
null,
|
||
|
\tool_usertours\configuration::get_default_value('placement'),
|
||
|
],
|
||
|
'Invalid value with default' => [
|
||
|
$allvalues,
|
||
|
'notavalue',
|
||
|
'somedefault',
|
||
|
'somedefault',
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test get_config with valid keys provided.
|
||
|
*
|
||
|
* @dataProvider get_config_provider
|
||
|
* @param object $values The config values
|
||
|
* @param string $key The key
|
||
|
* @param mixed $default The default value
|
||
|
* @param mixed $expected The expected value
|
||
|
*/
|
||
|
public function test_get_config_valid_keys($values, $key, $default, $expected) {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('config');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, $values);
|
||
|
|
||
|
$this->assertEquals($expected, $tour->get_config($key, $default));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check that a tour which has never been persisted is removed correctly.
|
||
|
*/
|
||
|
public function test_remove_non_persisted() {
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'get_steps',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->never())
|
||
|
->method('get_steps')
|
||
|
;
|
||
|
|
||
|
// Mock the database.
|
||
|
$DB = $this->mock_database();
|
||
|
$DB->expects($this->never())
|
||
|
->method('delete_records')
|
||
|
;
|
||
|
|
||
|
$this->assertNull($tour->remove());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check that a tour which has been persisted is removed correctly.
|
||
|
*/
|
||
|
public function test_remove_persisted() {
|
||
|
$id = rand(1, 100);
|
||
|
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'get_steps',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('id');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, $id);
|
||
|
|
||
|
$step = $this->getMockBuilder(\tool_usertours\step::class)
|
||
|
->setMethods([
|
||
|
'remove',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('get_steps')
|
||
|
->willReturn([$step])
|
||
|
;
|
||
|
|
||
|
// Mock the database.
|
||
|
$DB = $this->mock_database();
|
||
|
$DB->expects($this->once())
|
||
|
->method('delete_records')
|
||
|
->with($this->equalTo('tool_usertours_tours'), $this->equalTo(['id' => $id]))
|
||
|
->willReturn(null)
|
||
|
;
|
||
|
|
||
|
$DB->expects($this->once())
|
||
|
->method('get_records')
|
||
|
->with($this->equalTo('tool_usertours_tours'), $this->equalTo(null))
|
||
|
->willReturn([])
|
||
|
;
|
||
|
|
||
|
$this->assertNull($tour->remove());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Teset that sortorder is reset according to sortorder with values from 0.
|
||
|
*/
|
||
|
public function test_reset_step_sortorder() {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$mockdata = [];
|
||
|
for ($i = 4; $i >= 0; $i--) {
|
||
|
$id = rand($i * 10, ($i * 10) + 9);
|
||
|
$mockdata[] = (object) ['id' => $id];
|
||
|
$expectations[] = [$this->equalTo('tool_usertours_steps'), $this->equalTo('sortorder'), 4 - $i, ['id' => $id]];
|
||
|
}
|
||
|
|
||
|
// Mock the database.
|
||
|
$DB = $this->mock_database();
|
||
|
$DB->expects($this->once())
|
||
|
->method('get_records')
|
||
|
->willReturn($mockdata)
|
||
|
;
|
||
|
|
||
|
$setfield = $DB->expects($this->exactly(5))
|
||
|
->method('set_field')
|
||
|
;
|
||
|
call_user_func_array([$setfield, 'withConsecutive'], $expectations);
|
||
|
|
||
|
$tour->reset_step_sortorder();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test that a disabled tour should never be shown to users.
|
||
|
*/
|
||
|
public function test_should_show_for_user_disabled() {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
$tour->set_enabled(false);
|
||
|
|
||
|
$this->assertFalse($tour->should_show_for_user());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Provider for should_show_for_user.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function should_show_for_user_provider() {
|
||
|
$time = time();
|
||
|
return [
|
||
|
'Not seen by user at all' => [
|
||
|
null,
|
||
|
null,
|
||
|
null,
|
||
|
true,
|
||
|
],
|
||
|
'Completed by user before majorupdatetime' => [
|
||
|
$time - DAYSECS,
|
||
|
null,
|
||
|
$time,
|
||
|
true,
|
||
|
],
|
||
|
'Completed by user since majorupdatetime' => [
|
||
|
$time,
|
||
|
null,
|
||
|
$time - DAYSECS,
|
||
|
false,
|
||
|
],
|
||
|
'Requested by user before current completion' => [
|
||
|
$time,
|
||
|
$time - DAYSECS,
|
||
|
null,
|
||
|
false,
|
||
|
],
|
||
|
'Requested by user since completion' => [
|
||
|
$time - DAYSECS,
|
||
|
$time,
|
||
|
null,
|
||
|
true,
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test that a disabled tour should never be shown to users.
|
||
|
*
|
||
|
* @dataProvider should_show_for_user_provider
|
||
|
* @param mixed $completiondate The user's completion date for this tour
|
||
|
* @param mixed $requesteddate The user's last requested date for this tour
|
||
|
* @param mixed $updateddate The date this tour was last updated
|
||
|
* @param string $expectation The expected tour key
|
||
|
*/
|
||
|
public function test_should_show_for_user($completiondate, $requesteddate, $updateddate, $expectation) {
|
||
|
// Uses user preferences so we must be in a user context.
|
||
|
$this->resetAfterTest();
|
||
|
$this->setAdminUser();
|
||
|
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'get_id',
|
||
|
'get_config',
|
||
|
'is_enabled',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$tour->method('is_enabled')
|
||
|
->willReturn(true)
|
||
|
;
|
||
|
|
||
|
$id = rand(1, 100);
|
||
|
$tour->method('get_id')
|
||
|
->willReturn($id)
|
||
|
;
|
||
|
|
||
|
if ($completiondate !== null) {
|
||
|
set_user_preference(\tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER . $id, $completiondate);
|
||
|
}
|
||
|
|
||
|
if ($requesteddate !== null) {
|
||
|
set_user_preference(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id, $requesteddate);
|
||
|
}
|
||
|
|
||
|
if ($updateddate !== null) {
|
||
|
$tour->expects($this->once())
|
||
|
->method('get_config')
|
||
|
->willReturn($updateddate)
|
||
|
;
|
||
|
}
|
||
|
|
||
|
$this->assertEquals($expectation, $tour->should_show_for_user());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Provider for get_tour_key.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function get_tour_key_provider() {
|
||
|
$id = rand(1, 100);
|
||
|
$time = time();
|
||
|
|
||
|
return [
|
||
|
'No initial values' => [
|
||
|
$id,
|
||
|
[null, $time],
|
||
|
$this->greaterThanOrEqual($time),
|
||
|
true,
|
||
|
null,
|
||
|
sprintf('tool_usertours_\d_%d_%s', $id, $time),
|
||
|
],
|
||
|
|
||
|
'Initial tour time, no user pref' => [
|
||
|
$id,
|
||
|
[$time],
|
||
|
null,
|
||
|
false,
|
||
|
null,
|
||
|
sprintf('tool_usertours_\d_%d_%s', $id, $time),
|
||
|
],
|
||
|
'Initial tour time, with user reset lower' => [
|
||
|
$id,
|
||
|
[$time],
|
||
|
null,
|
||
|
false,
|
||
|
$time - DAYSECS,
|
||
|
sprintf('tool_usertours_\d_%d_%s', $id, $time),
|
||
|
],
|
||
|
'Initial tour time, with user reset higher' => [
|
||
|
$id,
|
||
|
[$time],
|
||
|
null,
|
||
|
false,
|
||
|
$time + DAYSECS,
|
||
|
sprintf('tool_usertours_\d_%d_%s', $id, $time + DAYSECS),
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test that get_tour_key provides the anticipated unique keys.
|
||
|
*
|
||
|
* @dataProvider get_tour_key_provider
|
||
|
* @param int $id The tour ID
|
||
|
* @param array $getconfig The mocked values for get_config calls
|
||
|
* @param array $setconfig The mocked values for set_config calls
|
||
|
* @param bool $willpersist Whether a persist is expected
|
||
|
* @param mixed $userpref The value to set for the user preference
|
||
|
* @param string $expectation The expected tour key
|
||
|
*/
|
||
|
public function test_get_tour_key($id, $getconfig, $setconfig, $willpersist, $userpref, $expectation) {
|
||
|
// Uses user preferences so we must be in a user context.
|
||
|
$this->resetAfterTest();
|
||
|
$this->setAdminUser();
|
||
|
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'get_config',
|
||
|
'set_config',
|
||
|
'get_id',
|
||
|
'persist',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
if ($getconfig) {
|
||
|
$tour->expects($this->exactly(count($getconfig)))
|
||
|
->method('get_config')
|
||
|
->will(call_user_func_array([$this, 'onConsecutiveCalls'], $getconfig))
|
||
|
;
|
||
|
}
|
||
|
|
||
|
if ($setconfig) {
|
||
|
$tour->expects($this->once())
|
||
|
->method('set_config')
|
||
|
->with($this->equalTo('majorupdatetime'), $setconfig)
|
||
|
->will($this->returnSelf())
|
||
|
;
|
||
|
} else {
|
||
|
$tour->expects($this->never())
|
||
|
->method('set_config')
|
||
|
;
|
||
|
}
|
||
|
|
||
|
if ($willpersist) {
|
||
|
$tour->expects($this->once())
|
||
|
->method('persist')
|
||
|
;
|
||
|
} else {
|
||
|
$tour->expects($this->never())
|
||
|
->method('persist')
|
||
|
;
|
||
|
}
|
||
|
|
||
|
$tour->expects($this->any())
|
||
|
->method('get_id')
|
||
|
->willReturn($id)
|
||
|
;
|
||
|
|
||
|
if ($userpref !== null) {
|
||
|
set_user_preference(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id, $userpref);
|
||
|
}
|
||
|
|
||
|
$this->assertRegExp(
|
||
|
'/' . $expectation . '/',
|
||
|
$tour->get_tour_key()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ensure that the request_user_reset function sets an appropriate value for the tour.
|
||
|
*/
|
||
|
public function test_requested_user_reset() {
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'get_id',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$id = rand(1, 100);
|
||
|
$time = time();
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('get_id')
|
||
|
->willReturn($id)
|
||
|
;
|
||
|
|
||
|
$tour->request_user_reset();
|
||
|
|
||
|
$this->assertGreaterThanOrEqual($time, get_user_preferences(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ensure that the request_user_reset function sets an appropriate value for the tour.
|
||
|
*/
|
||
|
public function test_mark_user_completed() {
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods([
|
||
|
'get_id',
|
||
|
])
|
||
|
->getMock()
|
||
|
;
|
||
|
|
||
|
$id = rand(1, 100);
|
||
|
$time = time();
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('get_id')
|
||
|
->willReturn($id)
|
||
|
;
|
||
|
|
||
|
$tour->mark_user_completed();
|
||
|
|
||
|
$this->assertGreaterThanOrEqual($time, get_user_preferences(\tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER . $id));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Provider for the is_first_tour and is_last_tour tests.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function sortorder_first_last_provider() {
|
||
|
$topcount = rand(10, 100);
|
||
|
return [
|
||
|
'Only tour => first + last' => [
|
||
|
0,
|
||
|
true,
|
||
|
1,
|
||
|
true,
|
||
|
],
|
||
|
'First tour of many' => [
|
||
|
0,
|
||
|
true,
|
||
|
$topcount,
|
||
|
false,
|
||
|
],
|
||
|
'Last tour of many' => [
|
||
|
$topcount - 1,
|
||
|
false,
|
||
|
$topcount,
|
||
|
true,
|
||
|
],
|
||
|
'Middle tour of many' => [
|
||
|
5,
|
||
|
false,
|
||
|
$topcount,
|
||
|
false,
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test the is_first_tour() function.
|
||
|
*
|
||
|
* @dataProvider sortorder_first_last_provider
|
||
|
* @param int $sortorder The new sort order
|
||
|
* @param bool $isfirst Whether this is the first tour
|
||
|
* @param int $total The number of tours
|
||
|
* @param bool $islast Whether this is the last tour
|
||
|
*/
|
||
|
public function test_is_first_tour($sortorder, $isfirst, $total, $islast) {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('sortorder');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, $sortorder);
|
||
|
|
||
|
$this->assertEquals($isfirst, $tour->is_first_tour());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test the is_last_tour() function.
|
||
|
*
|
||
|
* @dataProvider sortorder_first_last_provider
|
||
|
* @param int $sortorder The new sort order
|
||
|
* @param bool $isfirst Whether this is the first tour
|
||
|
* @param int $total The number of tours
|
||
|
* @param bool $islast Whether this is the last tour
|
||
|
*/
|
||
|
public function test_is_last_tour_calculated($sortorder, $isfirst, $total, $islast) {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('sortorder');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, $sortorder);
|
||
|
|
||
|
// The total will be calculated.
|
||
|
$DB = $this->mock_database();
|
||
|
$DB->expects($this->once())
|
||
|
->method('count_records')
|
||
|
->willReturn($total)
|
||
|
;
|
||
|
$this->assertEquals($islast, $tour->is_last_tour());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test the is_last_tour() function.
|
||
|
*
|
||
|
* @dataProvider sortorder_first_last_provider
|
||
|
* @param int $sortorder The new sort order
|
||
|
* @param bool $isfirst Whether this is the first tour
|
||
|
* @param int $total The number of tours
|
||
|
* @param bool $islast Whether this is the last tour
|
||
|
*/
|
||
|
public function test_is_last_tour_provided($sortorder, $isfirst, $total, $islast) {
|
||
|
$tour = new \tool_usertours\tour();
|
||
|
|
||
|
$rc = new \ReflectionClass(tour::class);
|
||
|
$rcp = $rc->getProperty('sortorder');
|
||
|
$rcp->setAccessible(true);
|
||
|
$rcp->setValue($tour, $sortorder);
|
||
|
|
||
|
// The total is provided.
|
||
|
// No DB calls expected.
|
||
|
$DB = $this->mock_database();
|
||
|
$DB->expects($this->never())
|
||
|
->method('count_records')
|
||
|
->willReturn(0)
|
||
|
;
|
||
|
$this->assertEquals($islast, $tour->is_last_tour($total));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Data provider for the get_filter_values tests.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function get_filter_values_provider() {
|
||
|
$cheese = ['cheddar', 'boursin', 'mozzarella'];
|
||
|
$horses = ['coolie', 'dakota', 'leo', 'twiggy'];
|
||
|
return [
|
||
|
'No config' => [
|
||
|
[],
|
||
|
'cheese',
|
||
|
[],
|
||
|
],
|
||
|
'Some config for another filter' => [
|
||
|
[
|
||
|
'horses' => $horses,
|
||
|
],
|
||
|
'cheese',
|
||
|
[],
|
||
|
],
|
||
|
'Some config for this filter' => [
|
||
|
[
|
||
|
'horses' => $horses,
|
||
|
],
|
||
|
'horses',
|
||
|
$horses,
|
||
|
],
|
||
|
'Some config for several filters' => [
|
||
|
[
|
||
|
'horses' => $horses,
|
||
|
'cheese' => $cheese
|
||
|
],
|
||
|
'horses',
|
||
|
$horses,
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Tests for the get_filter_values function.
|
||
|
*
|
||
|
* @dataProvider get_filter_values_provider
|
||
|
* @param array $fullconfig The config value being tested
|
||
|
* @param string $filtername The name of the filter being tested
|
||
|
* @param array $expectedvalues The expected result
|
||
|
*/
|
||
|
public function test_get_filter_values($fullconfig, $filtername, $expectedvalues) {
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods(['get_config'])
|
||
|
->getMock();
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('get_config')
|
||
|
->will($this->returnValue($fullconfig));
|
||
|
|
||
|
$this->assertEquals($expectedvalues, $tour->get_filter_values($filtername));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Data provider for set_filter_values tests.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function set_filter_values_provider() {
|
||
|
$cheese = ['cheddar', 'boursin', 'mozzarella'];
|
||
|
$horses = ['coolie', 'dakota', 'leo', 'twiggy'];
|
||
|
|
||
|
return [
|
||
|
'No initial value' => [
|
||
|
[],
|
||
|
'cheese',
|
||
|
$cheese,
|
||
|
['cheese' => $cheese],
|
||
|
],
|
||
|
'Existing filter merged' => [
|
||
|
['horses' => $horses],
|
||
|
'cheese',
|
||
|
$cheese,
|
||
|
['horses' => $horses, 'cheese' => $cheese],
|
||
|
],
|
||
|
'Existing filter updated' => [
|
||
|
['cheese' => $cheese],
|
||
|
'cheese',
|
||
|
['cheddar'],
|
||
|
['cheese' => ['cheddar']],
|
||
|
],
|
||
|
'Existing filter updated with merge' => [
|
||
|
['horses' => $horses, 'cheese' => $cheese],
|
||
|
'cheese',
|
||
|
['cheddar'],
|
||
|
['horses' => $horses, 'cheese' => ['cheddar']],
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Base tests for set_filter_values.
|
||
|
*
|
||
|
* @dataProvider set_filter_values_provider
|
||
|
* @param array $currentvalues The current value
|
||
|
* @param string $filtername The name of the filter to add to
|
||
|
* @param array $newvalues The new values to store
|
||
|
* @param array $expectedvalues The combined values
|
||
|
*/
|
||
|
public function test_set_filter_values_merge($currentvalues, $filtername, $newvalues, $expectedvalues) {
|
||
|
$tour = $this->getMockBuilder(tour::class)
|
||
|
->setMethods(['get_config', 'set_config'])
|
||
|
->getMock();
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('get_config')
|
||
|
->will($this->returnValue($currentvalues));
|
||
|
|
||
|
$tour->expects($this->once())
|
||
|
->method('set_config')
|
||
|
->with(
|
||
|
$this->equalTo('filtervalues'),
|
||
|
$this->equalTo($expectedvalues)
|
||
|
);
|
||
|
|
||
|
$tour->set_filter_values($filtername, $newvalues);
|
||
|
}
|
||
|
}
|