MDL-32149 PHPUnit test support - part 2
Includes: * constants refactoring * reworked db table init * support for $CFG->debug = -1 * functional DB tests * fixed $DB->get_indexes() to not throw exceptions when table does not exist * fix handling of user passwords in test db * add debug info to exception messages * removed unnecessary PHP debug errors from mathslib * fixed @error suppression in get_string * fixed PHPUnit error handler setup * added timezone info to default install
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('PHPUNIT_CLI_UTIL', true);
|
||||
define('PHPUNIT_UTIL', true);
|
||||
|
||||
require(__DIR__ . '/../../../../lib/phpunit/bootstrap.php');
|
||||
require_once($CFG->libdir.'/phpunit/lib.php');
|
||||
|
||||
@@ -490,6 +490,12 @@ $CFG->admin = 'admin';
|
||||
// $CFG->phpunit_prefix = 'phpu_';
|
||||
// $CFG->phpunit_dataroot = '/home/example/phpu_moodledata';
|
||||
// $CFG->phpunit_directorypermissions = 02777; // optional
|
||||
// $CFG->phpunit_extra_drivers = array(
|
||||
// 1=>array('dbtype'=>'mysqli', 'dbhost'=>'localhost', 'dbname'=>'moodle', 'dbuser'=>'root', 'dbpass'=>'', 'prefix'=>'phpu2_'),
|
||||
// 2=>array('dbtype'=>'pgsql', 'dbhost'=>'localhost', 'dbname'=>'moodle', 'dbuser'=>'postgres', 'dbpass'=>'', 'prefix'=>'phpu2_'),
|
||||
// 3=>array('dbtype'=>'sqlsrv', 'dbhost'=>'127.0.0.1', 'dbname'=>'moodle', 'dbuser'=>'sa', 'dbpass'=>'', 'prefix'=>'phpu2_'),
|
||||
// 4=>array('dbtype'=>'oci', 'dbhost'=>'127.0.0.1', 'dbname'=>'XE', 'dbuser'=>'sa', 'dbpass'=>'', 'prefix'=>'t_'),
|
||||
// ); // for database driver testing only, DB is selected via PHPUNIT_TEST_DRIVER=n
|
||||
|
||||
//=========================================================================
|
||||
// ALL DONE! To continue installation, visit your main page with a browser
|
||||
|
||||
+1
-1
@@ -217,7 +217,7 @@ $ACCESSLIB_PRIVATE->capabilities = null; // detailed information about th
|
||||
*/
|
||||
function accesslib_clear_all_caches_for_unit_testing() {
|
||||
global $UNITTEST, $USER;
|
||||
if (empty($UNITTEST->running) and !PHPUNITTEST) {
|
||||
if (empty($UNITTEST->running) and !PHPUNIT_TEST) {
|
||||
throw new coding_exception('You must not call clear_all_caches outside of unit tests.');
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<?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/>.
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for (some of) ../ajaxlib.php.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/ajax/ajaxlib.php');
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for ../ajaxlib.php functions.
|
||||
*
|
||||
* @copyright 2008 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class ajax_test extends UnitTestCase {
|
||||
|
||||
var $user_agents = array(
|
||||
'MSIE' => array(
|
||||
'5.5' => array('Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'),
|
||||
'6.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'),
|
||||
'7.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)')
|
||||
),
|
||||
'Firefox' => array(
|
||||
'1.0.6' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'),
|
||||
'1.5' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'),
|
||||
'1.5.0.1' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'),
|
||||
'2.0' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1',
|
||||
'Ubuntu Linux AMD64' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)')
|
||||
),
|
||||
'Safari' => array(
|
||||
'312' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312'),
|
||||
'2.0' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412')
|
||||
),
|
||||
'Opera' => array(
|
||||
'8.51' => array('Windows XP' => 'Opera/8.51 (Windows NT 5.1; U; en)'),
|
||||
'9.0' => array('Windows XP' => 'Opera/9.0 (Windows NT 5.1; U; en)',
|
||||
'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)')
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Uses the array of user agents to test ajax_lib::ajaxenabled
|
||||
*/
|
||||
function test_ajaxenabled()
|
||||
{
|
||||
global $CFG, $USER;
|
||||
$CFG->enableajax = true;
|
||||
$USER->ajax = true;
|
||||
|
||||
// Should be true
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
|
||||
$this->assertTrue(ajaxenabled());
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.5']['Windows XP'];
|
||||
$this->assertTrue(ajaxenabled());
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X'];
|
||||
$this->assertTrue(ajaxenabled());
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
|
||||
$this->assertTrue(ajaxenabled());
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2'];
|
||||
$this->assertTrue(ajaxenabled());
|
||||
|
||||
// Should be false
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.0.6']['Windows XP'];
|
||||
$this->assertFalse(ajaxenabled());
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['312']['Mac OS X'];
|
||||
$this->assertFalse(ajaxenabled());
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['8.51']['Windows XP'];
|
||||
$this->assertFalse(ajaxenabled());
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['5.5']['Windows 2000'];
|
||||
$this->assertFalse(ajaxenabled());
|
||||
|
||||
// Test array of tested browsers
|
||||
$tested_browsers = array('MSIE' => 6.0, 'Gecko' => 20061111);
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
|
||||
$this->assertTrue(ajaxenabled($tested_browsers));
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2'];
|
||||
$this->assertTrue(ajaxenabled($tested_browsers));
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X'];
|
||||
$this->assertFalse(ajaxenabled($tested_browsers));
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
|
||||
$this->assertFalse(ajaxenabled($tested_browsers));
|
||||
|
||||
$tested_browsers = array('Safari' => 412, 'Opera' => 9.0);
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
|
||||
$this->assertFalse(ajaxenabled($tested_browsers));
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2'];
|
||||
$this->assertFalse(ajaxenabled($tested_browsers));
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X'];
|
||||
$this->assertTrue(ajaxenabled($tested_browsers));
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
|
||||
$this->assertTrue(ajaxenabled($tested_browsers));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="lib/ddl/simpletest/fixtures" VERSION="20120122" COMMENT="This is an invalid xml file used for testing.">
|
||||
<TABLES>
|
||||
<TABLE NAME="test_table1" COMMENT="Just a test table">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="incorrect_next_field"/> <!-- invalid because of NEXT value -->
|
||||
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
|
||||
<FIELD NAME="name" TYPE="char" LENGTH="30" NOTNULL="false" SEQUENCE="false" DEFAULT="Moodle" PREVIOUS="course" NEXT="secondname"/>
|
||||
<FIELD NAME="secondname" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" PREVIOUS="name" NEXT="intro"/>
|
||||
<FIELD NAME="intro" TYPE="text" LENGTH="medium" NOTNULL="true" SEQUENCE="false" PREVIOUS="secondname" NEXT="avatar"/>
|
||||
<FIELD NAME="avatar" TYPE="binary" LENGTH="medium" NOTNULL="false" SEQUENCE="false" PREVIOUS="intro" NEXT="grade"/>
|
||||
<FIELD NAME="grade" TYPE="number" LENGTH="20" DECIMALS="10" NOTNULL="false" SEQUENCE="false" PREVIOUS="avatar"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="lib/ddl/simpletest/fixtures" VERSION="20120122" COMMENT="XMLDB file DLL unit tests">
|
||||
<TABLES>
|
||||
<TABLE NAME="test_table1" COMMENT="Just a test table">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="course"/>
|
||||
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
|
||||
<FIELD NAME="name" TYPE="char" LENGTH="30" NOTNULL="false" SEQUENCE="false" DEFAULT="Moodle" PREVIOUS="course" NEXT="secondname"/>
|
||||
<FIELD NAME="secondname" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" PREVIOUS="name" NEXT="intro"/>
|
||||
<FIELD NAME="intro" TYPE="text" LENGTH="medium" NOTNULL="true" SEQUENCE="false" PREVIOUS="secondname" NEXT="avatar"/>
|
||||
<FIELD NAME="avatar" TYPE="binary" LENGTH="medium" NOTNULL="false" UNSIGNED="false" SEQUENCE="false" PREVIOUS="intro" NEXT="grade"/>
|
||||
<FIELD NAME="grade" TYPE="number" LENGTH="20" DECIMALS="10" NOTNULL="false" SEQUENCE="false" PREVIOUS="avatar"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
@@ -410,7 +410,11 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
$sql = "SHOW INDEXES FROM {$this->prefix}$table";
|
||||
$this->query_start($sql, null, SQL_QUERY_AUX);
|
||||
$result = $this->mysqli->query($sql);
|
||||
$this->query_end($result);
|
||||
try {
|
||||
$this->query_end($result);
|
||||
} catch (dml_read_exception $e) {
|
||||
return $indexes; // table does not exist - no indexes...
|
||||
}
|
||||
if ($result) {
|
||||
while ($res = $result->fetch_object()) {
|
||||
if ($res->Key_name === 'PRIMARY') {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Vendored
+197
@@ -0,0 +1,197 @@
|
||||
제 1장 총 칙
|
||||
|
||||
제 1조 (개요)
|
||||
|
||||
이 약관은 전기통신사업법 및 동법 시행령에 의거 ㈜네오플(이하 "회사")이 제공하는 서비스 (이하 "서비스")의 이용조건, 절차, 의무, 책임사항 및 이용에 필요한 기타사항을 규정합니다.
|
||||
|
||||
제 2조 (목적)
|
||||
|
||||
이 약관은 다음과 같은 내용을 목적으로 합니다.
|
||||
1. 안정적인 서비스 제공 및 서비스, 시스템의 보호를 목적으로 한다.
|
||||
2. 이용자의 안정적인 서비스 이용 및 이용자의 데이타 보호를 목적으로 한다.
|
||||
3. 네트워크 및 서비스 이용자 네트워크의 안정성, 프라이버시, 보안성 유지를 목적으로 한다.
|
||||
4. 네트워크 및 서비스의 사용 원칙 가이드라인 제시를 목적으로 한다.
|
||||
|
||||
제 3조 (약관의 효력과 변경)
|
||||
|
||||
1. 회사는 귀하가 본 약관 내용에 동의하는 것을 조건으로 서비스를 제공 합니다.
|
||||
2. 이 약관은 서비스 내에 게시하여 공시함으로써 효력을 발생합니다.
|
||||
3. 당사의 서비스 제공 행위 및 귀하의 서비스 사용 행위에는 본 약관이 우선적으로 적용될 것입니다.
|
||||
4. 회사는 이 약관을 개정할 경우에는 적용일자 및 개정사유를 명시하여 현행약관과 함께 초기화면에 그 적용일자 7일이전부터 적용일자 전일까지 공지합니다.
|
||||
5. 이용자는 회원등록을 취소(회원탈퇴)할 수 있으며, 계속 사용의 경우는 약관 변경에 대한 동의로 간주됩니다. 변경된 약관은 공지와 동시에 그 효력이 발생됩니다.
|
||||
|
||||
제 4조 (약관외 준칙)
|
||||
|
||||
1. 서비스 이용에 관하여는 이 약관을 적용하며, 이 약관에 명시되지 아니 한 사항에 대하여는 전기통신 기본법, 전기통신사업법, 정보통신망 이용 촉진 및 정보보호 등에 관한 법률(이하통신망법), 기타 관련법령 및 회사의 공지,이용안내를 적용 합니다.
|
||||
2. 이 약관의 공지 및 변경사항은 회사의 지정된 홈페이지(http://www.candybar.co.kr)에 게시하는 방법으로 공지합니다.
|
||||
|
||||
제 5조 (용어의 정의)
|
||||
|
||||
이 약관에서 사용하는 용어의 정의는 다음과 같습니다.
|
||||
1. 이용자 : 서비스 이용을 신청하고 회사가 이를 승낙하여 회원ID를 발급 받은 자를 말합니다.
|
||||
2. 가 입 : 회사가 제공하는 양식에 해당 정보를 기입하고, 이 약관에 동의하여 서비스 이용계약을 완료시키는 행위를 말합니다.
|
||||
3. 회 원 : 회사에 개인 정보를 제공하여 회원 등록을 한 자로서, 회사가 제공하는 서비스를 이용할 수 있는 자를 말합니다.
|
||||
4. 캔디바 ID : 회원의 서비스 이용을 위하여 회원이 신청하고 회사가 승인하는 문자 및 숫자의 조합을 말합니다.
|
||||
5. 비밀번호 : 회원ID가 일치하는지를 확인하고 자신의 비밀보호를 위하여 이용자 자신이 선정한 문자와 숫자의 조합을 말합니다.
|
||||
6. 탈퇴 및 해지 : 회원이 이용계약을 종료 시키는 행위를 말합니다.
|
||||
|
||||
제 2장 서비스 이용 계약
|
||||
|
||||
제 6조 (이용 계약의 성립)
|
||||
|
||||
1. 이용계약은 당사 소정의 가입신청 양식에서 요구하는 사항을 기록하여 가입을 완료 하는것으로 성립함을 원칙으로 합니다.
|
||||
2. 이용신청은 이용신청자 자신의 실명으로 하여야 합니다. 실명이 아닌경우는 여러가지 불이익을 받을수 도 있습니다.
|
||||
3. 이용계약은 서비스 이용희망자의 이용약관 동의 후 이용 신청에 대하여 회사가 승낙함으로써 성립합니다.
|
||||
4. 서비스 이용 희망자가 14세 미만의 미성년자 또는 한정치산자인 경우 부모등 법정대리인의 동의를 받아 이용신청하며 납입책임자는 법정대리인으로 합니다. 또한 금치산자인 경우에는 법정대리인 을 이용자 및 납입책임자로 하여 신청합니다.
|
||||
|
||||
제 7조 (이용신청의 승낙)
|
||||
1. 회사는 제 6조의 규정에 의한 서비스 이용희망자에 대하여 업무수행상 또는 기술상 지장이 없는 경우에는 원칙적으로 접수순서에 따라 이용신청을 승낙합니다.
|
||||
2. 이용자의 이용신청에 대하여 회사가 이를 승낙한 경우, 회사는 회원 ID와 기타 회사가 필요하다고 인정하는 내용을 이용자에게 통지합니다.
|
||||
|
||||
제 8조 (이용신청에 대한 불승낙과 승낙의 보류)
|
||||
1. 이용자가 신청한 이용 아이디(ID)가 이미 다른 이용자에 의해 쓰여지고 있는 경우 승낙을 하지 아니할 수 있습니다.
|
||||
2. 회사는 다음 각호에 해당하는 이용신청에 대하여는 승낙을 하지 아니할 수 있습니다.
|
||||
1) 타인 명의의 신청
|
||||
2) 허위의 신청이거나 허위사실을 기재한 경우 예) 주민등록 생성기를 이용한 비실명 가입
|
||||
3) 기타 이용신청고객의 귀책사유로 이용승낙이 곤란한 경우
|
||||
3. 회사는 전항의 경우에는 이를 이용신청고객에게 가능한 빠른 시일 내에 통지하여야 합니다.
|
||||
4. 회사는 이용신청고객이 미성년자, 한정치산자인 경우에 법정대리인(부모 등)의 동의없는 이용신청에 대하여 승낙을 보류할 수 있습니다.
|
||||
5. 회사는 이용신청이 불승낙되거나 승낙을 제한하는 경우에는 이를 이용신청자에게 즉시 통보합니다.
|
||||
|
||||
제 9조 (이용 아이디 관리 및 변경)
|
||||
|
||||
1. 이용 아이디(ID) 및 비밀번호에 대한 모든 관리책임은 이용자에게 있습니다.
|
||||
2. 이용 아이디(ID)는 다음에 해당하는 경우에는 이용자와 합의하여 변경할 수 있습니다.
|
||||
(단, 이용 아이디(ID)를 변경할 경우 기존 이용ID는 소멸됩니다.)
|
||||
1) 이용 아이디(ID)가 이용자의 전화번호 또는 주민등록번호 등으로 등록되어 사생활 침해가 우려 되는 경우
|
||||
2) 타인에게 혐오감을 주거나 미풍양속에 어긋나는 경우
|
||||
3) 기타 회사가 인정하는 합리적인 사유가 있는 경우
|
||||
3. 회사는 이용 아이디(ID)에 의하여 서비스 이용요금 청구 및 게시판 관리 등 제반 이용자 관리 업무를 수행하며 이용자는 이용 아이디(ID)를 공유, 양도 또는 변경할 수 없습니다. 단, 그 사유가 명백하고 회사가 인정하는 경우에는 그러하지 아니 합니다.
|
||||
4. 이용자가 신청 또는 변경하여 사용하는 이용 아이디(ID) 및 비밀번호에 의하여 발생하는 서비스 이용상의 과실 또는 제3자에 의한 부정사용등에 대한 모든 책임은 이용자에게 있습니다. 단, 회사의 고의 또는 중대한 과실이 있는 경우에는 그러하지 아니합니다.
|
||||
5. 기타 아이디의 관리 및 변경 등에 관한 사항은 이 약관과 회사의 공지, 이용안내 에서 정하는 바에 의합니다.
|
||||
|
||||
제 3장 계약당사자의 의무 및 책임
|
||||
|
||||
제 10조 (회사의 의무)
|
||||
|
||||
1. 회사는 이용자로부터 제기되는 의견이나 불만이 정당하다고 인정할 경우에는 즉시 처리하여야 합니다. 즉시 처리가 곤란한 경우에는 그 사유와 처리일정을 서면 또는 전화 등으로 통보합니다.
|
||||
2. 회사는 서비스 제공과 관련하여 취득한 이용자의 정보를 본인의 동의없이 타인에게 누설 배포할 수 없으며 서비스 관련 업무 이외의 목적으로도 사용할 수 없습니다.
|
||||
3. 제2항의 경우 관계법령에 의한 규정에 의하여 수사상의 목적으로 관계기관으로부터 요구받은 경우나 정보통신윤리위원회의 요청이 있는 경우 또는 통신망법 24조 1항 '정보통신서비스의 제공에 따른 요금정산을 위하여 필요한 경우'에는 개인정보의 이용 혹은 제 3자에게 제공될수 있으며 그 범위는 회사의 개인정보보호정책을 따릅니다.
|
||||
4. 회사는 계속적이고 안정적인 서비스 제공을 위하여 설비에 장애가 생기거나 멸실된 경우에는 지체없이 이를 수리 또는 복구하며, 서비스를 다시 이용할 수 있게 된 경우 이 사실을 이용자에게 통지하여야 합니다. 단 천재지변, 비상사태 또는 그밖의 부득이한 경우에는 서비스를 일시 중단하거나 중지할 수 있습니다.
|
||||
5. 회사는 이용계약의 체결, 계약사항의 변경 및 해지 등 이용자와의 계약에 관련된 절차 및 내용 등에 있어서 이용자에게 편의를 제공하도록 노력합니다.
|
||||
6. 회사는 이용자가 안전하게 당사서비스를 이용할 수 있도록 이용자의 개인정보(신용정보 포함)보호를 위한 보안시스템을 갖추어야 합니다.
|
||||
7. 회사는 이용자가 제11조의 이용자의 의무를 위반한 경우 및 고의 또는 중대한 과실로 회사에 손해를 입힌 경우에는 사전 통보 없이 이용계약을 해지하거나 또는 기간을 정하여 서비스의 이용을 중지할 수 있습니다.
|
||||
|
||||
제 11 조 (이용자의 의무)
|
||||
|
||||
1. 이용자는 이 약관에서 규정하는 사항과 서비스 이용안내 또는 주의사항을 준수하여야 하며,기타 회사의 업무수행에 현저한 지장을 초래하는 행위를 하여서는 아니 됩니다.
|
||||
2. 이용자는 서비스를 이용함에 있어 문제 발생소지 정보의 책임은 이용자에게 있습니다.
|
||||
3. 이용자는 서비스를 이용하여 얻은 정보를 가공, 판매하는 행위 등 게재 된 자료를 상업적으로 이용할 수 없으며 이를 위반하여 발생하는 제반 문제에 대한 책임은 이용자에게 있습니다.
|
||||
4. 이용자는 이용계약에 따라 요금을 지불하여야 하며, 서비스 이용요금의 미납으로 인하여 발생되는 모든 문제에 대한 책임은 이용자에게 있습니다. 단, 회사의 고의 또는 중과실의 경우에는 그러하지 아니 합니다.
|
||||
5. 이용자는 회원가입시 정보는 정확하게 기입하여야 합니다. 주민등록생성기등을 이용하여 허위로 가입을 하거나 주민등록 생성기를 인터넷에 올리거나 이를 이용해 만든 행위에 관하여서도 주민등록법 개정안에 의거하여 엄중히 법적인 제재를 가할 수 있습니다. 또한 이미 제공된 귀하에 대한 정보가 정확한 정보가 되도록 유지, 갱신하여야 하며, 회원은 자신의 캔디바 ID 및 비밀번호를 제3자에게 이용하게 해서는 안됩니다.
|
||||
6. 이용자는 당사의 사전 승낙없이 서비스를 이용하여 어떠한 영리행위도 할 수 없습니다.
|
||||
7. 이용자는 당사 서비스를 이용하여 얻은 정보를 당사의 사전승낙 없이 복사, 복제, 변경, 번역, 출판·방송 기타의 방법으로 사용하거나 이를 타인에게 제공할 수 없습니다.
|
||||
8. 이용자는 당사 서비스 이용과 관련하여 다음 각 호의 행위를 하여서는 안됩니다.
|
||||
1) 다른 회원의 캔디바 ID를 부정 사용하는 행위
|
||||
2) 범죄행위를 목적으로 하거나 기타 범죄행위와 관련된 행위
|
||||
3) 선량한 풍속, 기타 사회질서를 해하는 행위
|
||||
4) 타인의 명예를 훼손하거나 모욕하는 행위
|
||||
5) 타인의 지적재산권 등의 권리를 침해하는 행위
|
||||
6) 해킹행위 또는 컴퓨터 바이러스의 유포행위
|
||||
7) 타인의 의사에 반하여 광고성 정보 등 일정한 내용을 지속적으로 전송하는 행위
|
||||
8) 서비스의 안전적인 운영에 지장을 주거나 줄 우려가 있는 일체의 행위
|
||||
9) 당사 사이트에 게시된 정보의 변경
|
||||
10) 기타 전기통신법 제53조와 전기통신사업법 시행령 16조(불온통신), 통신사업법 제53조3항에 위배되는 행위
|
||||
9. 다른 이용자들에게 피해를 주는 다음 각 호에 해당하는 행위를 하여서는 안됩니다.
|
||||
1) 회사가 인정하는 서비스의 공식 운영자인 아이디를 사칭하는 내용
|
||||
2) 선정적이고 음란한 내용
|
||||
3) 반사회적이고 관계법령에 저촉되는 내용
|
||||
4) 기타 제3자의 상표권, 저작권에 위배될 가능성이 있는 내용
|
||||
5) 비어, 속어라고 판단되는 내용
|
||||
6) 욕설이나 노골적인 성 묘사를 하는 내용
|
||||
7) 다른 이용자를 희롱하거나, 위협하거나, 특정 이용자에게 지속적으로 고통을 주거나,불편을 주는 행위
|
||||
8) 서비스 내 또는 웹사이트 상에서 다른 회사 제품의 광고나 판촉활동을 하는 행위
|
||||
9) 저작권자의 허가 없이 저작권 문제가 발생할 소지가 있는 내용을 서비스 내 또는 웹사이트 상에 배포하는 행위
|
||||
|
||||
제 4장 서비스 이용·제한·정지등
|
||||
|
||||
제 12조 (서비스의 이용)
|
||||
|
||||
1. 캔디바 서비스의 이용은 기본적으로 무료입니다. 단 회사에서 정한 별도의 유효정보 및 유료서비스에 대해서는 그러지 아니하며, 유료서비스 이용에 관한 사항은 회사가 별도로 정한 약관 및 정책에 따릅니다.
|
||||
2. 유료 서비스 이용의 결제에 관한 사항(충전방법, 사용, 환불 등)은 바(Bar)정책 이용약관에 따릅니다.
|
||||
3. 아바타 및 게임 아이템 등 유료서비스의 소유권은 회사에 있으며, 웹상의 사용권은 해당 컨텐츠를 구매한 이용자에게 있습니다.
|
||||
|
||||
제 13조 (서비스 이용시간 및 중지)
|
||||
|
||||
1. 서비스 이용은 회사의 업무상 또는 기술상 특별한 지장이 없는 한 연중 무휴, 1일 24시간을 원칙으로 합니다. 다만, 회사는 서비스의 데이터 베이스별로 이용가능시간을 정할 수 있으며, 이 경우 그 내용은 회사가 정하여 서비스에 게시하거나 별도로 공시하는 바에 따릅니다.
|
||||
1) 제1항의 규정에도 불구하고 정기점검 등의 필요로 회사가 정한 날 또는 시간은 예외적으로 서비스 이용을 제한할 수 있습니다.
|
||||
2. 전시,사변,천재지변 또는 이에 준하는 국가비상사태가 발생하거나 발생할 우려가 있는 경우와 전기통신사업법에 의한 기간통신사업자가 전기통신서비스를 중지하는등 기타 부득이한 사유가 있는 경우에는 서비스의 전부 또는 일부를 제한하거나 정지할 수 있습니다.
|
||||
1) 회사는 제1항의 규정에 의하여 서비스의 전부 또는 일부를 제한하거나 정지한 때에는 지체없이 이용자에게 알려야 합니다.
|
||||
3. 이용자가 국익 또는 사회적 공익을 저해할 목적이나 범죄적 목적으로 서비스를 이용하고 있다고 판단되는 경우에 회사는 이용자에게 사전 통보 없이 서비스를 중단할 수 있으며 그에 따른 데이터도 복구를 전제로 하지않고 삭제할 수 있습니다.
|
||||
4. 회사는 이용정지 기간 중에 사유가 해소된 것이 확인된 경우에는 지체없이 서비스를 재개통 또는 이용정지를 해제합니다.
|
||||
|
||||
제 14조 (각종 자료의 저장기간)
|
||||
|
||||
회사는 필요한 경우 서비스의 일정 부분별로 이용자가 게시한 자료나 이용자의 필요에 의해 저장하고 있는 자료에 대해 일정한 게재기간 또는 저장기간을 정할 수 있으며, 필요에 따라 기간을 변경할 수 있습니다.
|
||||
|
||||
제 15조 (게시물의 저작권)
|
||||
|
||||
1. 이용자가 서비스 홈페이지에 게시하거나 등록한 자료의 지적재산권은 이용자에게 귀속됩니다. 단, 회사는 서비스 홈페이지의 게재권을 가지며 비상업적 목적으로는 이용자의 게시물을 활용할 수 있습니다.
|
||||
2. 이용자는 서비스를 이용하여 얻은 정보를 가공, 판매하는 행위 등 게재 된 자료를 상업적으로 이용할 수 없으며 이를 위반하여 발생하는 제반 문제에 대한 책임은 이용자에게 있습니다.
|
||||
3. 회사는 이용자 게시물의 내용 검열, 검색 및 관리에 따른 일체의 손해배상 책임을 지지아니 합니다.
|
||||
|
||||
제 5장 개인정보 보호
|
||||
|
||||
제 16조 개인정보보호
|
||||
회사는 관계법령이 정하는 바에 따라 회원등록정보를 포함한 회원의 개인정보를 보호하기 위하여 노력을 합니다. 회원의 개인정보보호에 관하여 관계법령 및 회사가 정하는 개인정보보호정책에 정한 바에 따릅니다.
|
||||
|
||||
제 6장 계약해지 및 이용제한
|
||||
|
||||
제 17조 (계약의 해지)
|
||||
|
||||
회원이 이용계약을 해지하고자 하는 경우에는 회원 본인이 온라인을 통하여 등록해지신청을 하여야 합니다.
|
||||
|
||||
제 18조 (이용제한)
|
||||
|
||||
1. 회사는 회원이 다음 각 호의 사유에 해당하는 경우 사전통지 없이 회원의 서비스 이용제한 및 적법한 조치를 취할 수 있으며 이용계약을 해지하거나 또는 기간을 정하여 서비스를 중지할 수 있습니다.
|
||||
1) 회원 가입신청 또는 변경시 허위 내용을 등록한 경우
|
||||
2) 타인의 서비스 이용을 방해하거나 그 정보를 도용한 경우
|
||||
3) 회사의 운영진, 직원 또는 관계자를 사칭하는 경우
|
||||
4) 회사의 사전승락없이 서비스를 이용하여 영업활동을 하는 경우
|
||||
5) 회원ID를 타인과 거래하거나 회원ID의 게임상 사이버 자산을 타인과 매매하는 행위를 하는 경우
|
||||
6) 회사 프로그램상의 버그를 악용하여 정상적이지 아니한 방법으로 게임상 사이버자산을 취득하는 행위를 하는 경우
|
||||
7) 서비스를 통하여 얻은 정보를 회사의 사전승낙없이 서비스 이용 외이 목적으로 복제하거나 이를 출판 및 방송 등에 사용하거나, 제3자에게 제공하는 경우
|
||||
8) 회사 또는 제3자의 저작권 등 기타 지적재산권을 침해하는 내용을 전송, 게시, 전자우편 또는 기타의 방법으로 타인에게 유포하는 경우
|
||||
9) 공공질서 및 미풍약속에 위반되는 음란한 내용의 정보, 문장, 도형, 음향, 동영상을 전송, 게시, 전자우편 또는 기타의 방법으로 타인에게 유포하는 경우
|
||||
10) 심히 모욕적이거나 개인신상에 대한 내용이어서 타인의 명예나 프라이버시를 침해할 수 있는 내용을 전송, 게시, 전자우편 또는 기타의 방법으로 타인에게 유포하는 경우
|
||||
11) 서비스에 위해를 가하거나 고의로 방해한 경우
|
||||
12) 다른 회원을 희롱, 위협하거나 특정 이용자에게 지속적으로 고통, 불편을 주는 행위를 하는 경우
|
||||
13) 범죄와 관련이 있다고 객관적으로 판단되는 행위를 하는 경우
|
||||
14) 본 서비스를 이용함에 있어 본 약관 및 기타 회사가 정한 정책 또한 운영 규칙을 위반하는 경우
|
||||
15) 기타 관련 법령에 위배하는 행위를 하는 경우
|
||||
|
||||
제 7장 분쟁조정 및 기타사항
|
||||
|
||||
제 19조 (손해배상)
|
||||
|
||||
회사는 무료로 제공되는 서비스 이용과 관련하여 회원에게 발생한 어떠한 손해에 관하여도 책임을 지지 않습니다.
|
||||
|
||||
제 20조 (면책조항)
|
||||
|
||||
1. 회사는 천재지변 또는 이에 준하는 불가항력으로 인하여 서비스를 제공 할 수 없는 경우에는 서비스 제공에 관한 책임이 면제됩니다.
|
||||
2. 회사는 회원의 귀책사유로 인한 서비스 이용의 장애에 대하여 책임을 지지 않습니다.
|
||||
3. 회사는 회원이 서비스를 이용하여 기대하는 수익을 상실한 것이나 서비스를 통하여 얻은 자료로 인한 손해에 관하여 책임을 지지 않습니다.
|
||||
4. 회사는 회원이 서비스에 게재한 정보, 자료, 사실의 신뢰도, 정확성 등 내용에 관하여는 책임을 지지 않습니다.
|
||||
5. 회사는 서비스 이용과 관련하여 가입자에게 발생한 손해 가운데 가입자의 고의, 과실에 의한 손해에 대하여 책임을 지지 않습니다.
|
||||
6. 회사는 회원간 또는 회원과 제3자간에 서비스를 매개로 하여 물품거래 혹은 금전적 거래등과 관련하여 어떠한 책임도 부담하지 않습니다.
|
||||
|
||||
|
||||
제 21조(분쟁조정)
|
||||
|
||||
회사와 이용고객은 개인정보에 관한 분쟁이 있는 경우 신속하고 효과적인 분쟁해결을 위하여 한국정보보호진흥원내의 개인정보분쟁조정위원회에 그 처리를 의뢰할 수 있습니다.
|
||||
|
||||
|
||||
제 22조(회사의 소유권)
|
||||
|
||||
1. 회사의 서비스, 소프트웨어, 이미지, 마크, 로고, 디자인, 서비스명칭, 정보 및 상표 등과 관련된 지적재산권 및 기타 권리는 회사에게 소유권이 있습니다.
|
||||
2. 이용자는 회사가 명시적으로 승인한 경우를 제외하고는 전항의 소정의 각 재산에 대한 전부 또는 일부의 수정, 대여, 대출, 판매, 배포, 제 작, 양도, 재라이센스, 담보권 설정 행위, 상업적 이용 행위를 할 수 없으며, 제3자로 하여금 이와 같은 행위를 하도록 허락할 수 없습니다.
|
||||
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,127 @@
|
||||
<?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/>.
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for forms lib.
|
||||
*
|
||||
* This file contains all unit test related to forms library.
|
||||
*
|
||||
* @package core_form
|
||||
* @category phpunit
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/form/duration.php');
|
||||
|
||||
/**
|
||||
* Unit tests for MoodleQuickForm_duration
|
||||
*
|
||||
* Contains test cases for testing MoodleQuickForm_duration
|
||||
*
|
||||
* @package core_form
|
||||
* @category unittest
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class duration_form_element_testcase extends basic_testcase {
|
||||
/** @var MoodleQuickForm_duration Keeps reference of MoodleQuickForm_duration object */
|
||||
private $element;
|
||||
|
||||
/**
|
||||
* Initalize test wide variable, it is called in start of the testcase
|
||||
*/
|
||||
function setUp() {
|
||||
$this->element = new MoodleQuickForm_duration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the data set in the setUp() method call.
|
||||
* @see duration_form_element_test::setUp()
|
||||
*/
|
||||
function tearDown() {
|
||||
$this->element = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for testing contructor.
|
||||
* @expectedException coding_exception
|
||||
* @retrun void
|
||||
*/
|
||||
function test_constructor() {
|
||||
// Test trying to create with an invalid unit.
|
||||
$this->element = new MoodleQuickForm_duration('testel', null, array('defaultunit' => 123));
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for testing units (seconds, minutes, hours and days)
|
||||
*/
|
||||
function test_get_units() {
|
||||
$units = $this->element->get_units();
|
||||
ksort($units);
|
||||
$this->assertEquals($units, array(1 => get_string('seconds'), 60 => get_string('minutes'),
|
||||
3600 => get_string('hours'), 86400 => get_string('days')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for testing conversion of seconds to the best possible unit
|
||||
*/
|
||||
function test_seconds_to_unit() {
|
||||
$this->assertEquals($this->element->seconds_to_unit(0), array(0, 60)); // Zero minutes, for a nice default unit.
|
||||
$this->assertEquals($this->element->seconds_to_unit(1), array(1, 1));
|
||||
$this->assertEquals($this->element->seconds_to_unit(3601), array(3601, 1));
|
||||
$this->assertEquals($this->element->seconds_to_unit(60), array(1, 60));
|
||||
$this->assertEquals($this->element->seconds_to_unit(180), array(3, 60));
|
||||
$this->assertEquals($this->element->seconds_to_unit(3600), array(1, 3600));
|
||||
$this->assertEquals($this->element->seconds_to_unit(7200), array(2, 3600));
|
||||
$this->assertEquals($this->element->seconds_to_unit(86400), array(1, 86400));
|
||||
$this->assertEquals($this->element->seconds_to_unit(90000), array(25, 3600));
|
||||
|
||||
$this->element = new MoodleQuickForm_duration('testel', null, array('defaultunit' => 86400));
|
||||
$this->assertEquals($this->element->seconds_to_unit(0), array(0, 86400)); // Zero minutes, for a nice default unit.
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase to check generated timestamp
|
||||
*/
|
||||
function test_exportValue() {
|
||||
$el = new MoodleQuickForm_duration('testel');
|
||||
$el->_createElements();
|
||||
$values = array('testel' => array('number' => 10, 'timeunit' => 1));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 10));
|
||||
$values = array('testel' => array('number' => 3, 'timeunit' => 60));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 180));
|
||||
$values = array('testel' => array('number' => 1.5, 'timeunit' => 60));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 90));
|
||||
$values = array('testel' => array('number' => 2, 'timeunit' => 3600));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 7200));
|
||||
$values = array('testel' => array('number' => 1, 'timeunit' => 86400));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 86400));
|
||||
$values = array('testel' => array('number' => 0, 'timeunit' => 3600));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 0));
|
||||
|
||||
$el = new MoodleQuickForm_duration('testel', null, array('optional' => true));
|
||||
$el->_createElements();
|
||||
$values = array('testel' => array('number' => 10, 'timeunit' => 1));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 0));
|
||||
$values = array('testel' => array('number' => 20, 'timeunit' => 1, 'enabled' => 1));
|
||||
$this->assertEquals($el->exportValue($values), array('testel' => 20));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -50,7 +50,7 @@ class calc_formula {
|
||||
*/
|
||||
function calc_formula($formula, $params=false) {
|
||||
$this->_em = new EvalMath();
|
||||
$this->_em->suppress_errors = !debugging('', DEBUG_DEVELOPER);
|
||||
$this->_em->suppress_errors = true; // no PHP errors!
|
||||
if (strpos($formula, '=') !== 0) {
|
||||
$this->_error = "missing leading '='";
|
||||
return;
|
||||
|
||||
+13
-8
@@ -10755,17 +10755,22 @@ class lang_string {
|
||||
$this->a = $a;
|
||||
} else if ($a instanceof lang_string) {
|
||||
$this->a = $a->out();
|
||||
} else if (is_object($a)) {
|
||||
$this->a = new stdClass;
|
||||
foreach (get_object_vars($a) as $key => $value) {
|
||||
// Make sure conversion errors don't get displayed (results in '')
|
||||
$this->a->$key = @(string)$value;
|
||||
}
|
||||
} else if (is_array($a)) {
|
||||
} else if (is_object($a) or is_array($a)) {
|
||||
$a = (array)$a;
|
||||
$this->a = array();
|
||||
foreach ($a as $key => $value) {
|
||||
// Make sure conversion errors don't get displayed (results in '')
|
||||
$this->a[$key] = @(string)$value;
|
||||
if (is_array($value)) {
|
||||
$this->a[$key] = '';
|
||||
} else if (is_object($value)) {
|
||||
if (method_exists($value, '__toString')) {
|
||||
$this->a[$key] = $value->__toString();
|
||||
} else {
|
||||
$this->a[$key] = '';
|
||||
}
|
||||
} else {
|
||||
$this->a[$key] = (string)$value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-17
@@ -22,7 +22,8 @@
|
||||
* 1 - general error
|
||||
* 130 - coding error
|
||||
* 131 - configuration problem
|
||||
* 132 - drop data, then install new test database
|
||||
* 132 - install new test database
|
||||
* 133 - drop old data, then install new test database
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
@@ -36,13 +37,24 @@ ini_set('display_errors', '1');
|
||||
ini_set('log_errors', '1');
|
||||
|
||||
if (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
phpunit_bootstrap_error('Unit tests can be executed only from commandline!', 1);
|
||||
phpunit_bootstrap_error('Unit tests can be executed only from command line!', 1);
|
||||
}
|
||||
|
||||
if (defined('PHPUNITTEST')) {
|
||||
phpunit_bootstrap_error("PHPUNITTEST constant must not be manually defined anywhere!", 130);
|
||||
if (defined('PHPUNIT_TEST')) {
|
||||
phpunit_bootstrap_error("PHPUNIT_TEST constant must not be manually defined anywhere!", 130);
|
||||
}
|
||||
/** PHPUnit testing framework active */
|
||||
define('PHPUNIT_TEST', true);
|
||||
|
||||
if (!defined('PHPUNIT_LONGTEST')) {
|
||||
/** Execute longer version of tests */
|
||||
define('PHPUNIT_LONGTEST', false);
|
||||
}
|
||||
|
||||
if (!defined('PHPUNIT_UTIL')) {
|
||||
/** Identifies utility scripts */
|
||||
define('PHPUNIT_UTIL', false);
|
||||
}
|
||||
define('PHPUNITTEST', true);
|
||||
|
||||
if (defined('CLI_SCRIPT')) {
|
||||
phpunit_bootstrap_error('CLI_SCRIPT must not be manually defined in any PHPUnit test scripts', 130);
|
||||
@@ -56,9 +68,10 @@ define('ABORT_AFTER_CONFIG', true);
|
||||
require(__DIR__ . '/../../config.php');
|
||||
|
||||
// remove error handling overrides done in config.php
|
||||
error_reporting(E_ALL);
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('log_errors', '1');
|
||||
set_time_limit(0); // no time limit in CLI scripts, user may cancel execution
|
||||
|
||||
// prepare dataroot
|
||||
umask(0);
|
||||
@@ -113,7 +126,10 @@ if (!file_exists("$CFG->phpunit_dataroot/phpunittestdir.txt")) {
|
||||
|
||||
// verify db prefix
|
||||
if (!isset($CFG->phpunit_prefix)) {
|
||||
phpunit_bootstrap_error('Missing $CFG->phpunit_dataroot in config.php, can not run tests!', 131);
|
||||
phpunit_bootstrap_error('Missing $CFG->phpunit_prefix in config.php, can not run tests!', 131);
|
||||
}
|
||||
if ($CFG->phpunit_prefix === '') {
|
||||
phpunit_bootstrap_error('$CFG->phpunit_prefix can not be empty, can not run tests!', 131);
|
||||
}
|
||||
if (isset($CFG->prefix) and $CFG->prefix === $CFG->phpunit_prefix) {
|
||||
phpunit_bootstrap_error('$CFG->prefix and $CFG->phpunit_prefix must not be identical, can not run tests!', 131);
|
||||
@@ -141,12 +157,14 @@ unset($allowed);
|
||||
unset($productioncfg);
|
||||
|
||||
// force the same CFG settings in all sites
|
||||
$CFG->debug = (E_ALL | E_STRICT | 38911); // can not use DEBUG_DEVELOPER here
|
||||
$CFG->debug = (E_ALL | E_STRICT); // can not use DEBUG_DEVELOPER yet
|
||||
$CFG->debugdisplay = 1;
|
||||
error_reporting($CFG->debug);
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('log_errors', '0');
|
||||
|
||||
$CFG->passwordsaltmain = 'phpunit'; // makes login via normal UI impossible
|
||||
|
||||
$CFG->noemailever = true; // better not mail anybody from tests, override temporarily if necessary
|
||||
$CFG->cachetext = 0; // disable this very nasty setting
|
||||
|
||||
@@ -163,20 +181,27 @@ require("$CFG->dirroot/lib/setup.php");
|
||||
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
|
||||
if (defined('PHPUNIT_CLI_UTIL')) {
|
||||
// all other tests are done in the CLI scripts...
|
||||
if (PHPUNIT_UTIL) {
|
||||
// we are not going to do testing, this is 'true' in utility scripts that init database usually
|
||||
return;
|
||||
}
|
||||
|
||||
if (!phpunit_util::is_testing_ready()) {
|
||||
phpunit_bootstrap_error('Database is not initialised to run unit tests, please use "php admin/tool/phpunit/cli/util.php --install"', 132);
|
||||
// is database and dataroot ready for testing?
|
||||
$problem = phpunit_util::testing_ready_problem();
|
||||
|
||||
if ($problem) {
|
||||
switch ($problem) {
|
||||
case 132:
|
||||
phpunit_bootstrap_error('Database was not initialised to run unit tests, please use "php admin/tool/phpunit/cli/util.php --install"', $problem);
|
||||
case 133:
|
||||
phpunit_bootstrap_error('Database was initialised for different version, please use "php admin/tool/phpunit/cli/util.php --drop; php admin/tool/phpunit/cli/util.php --install"', $problem);
|
||||
default:
|
||||
phpunit_bootstrap_error('Unknown problem initialising test database', $problem);
|
||||
}
|
||||
}
|
||||
|
||||
// refresh data in all tables, clear caches, etc.
|
||||
phpunit_util::reset_all_data();
|
||||
|
||||
// store fresh globals
|
||||
phpunit_util::init_globals();
|
||||
// prepare for the first test run - store fresh globals, reset dataroot, etc.
|
||||
phpunit_util::bootstrap_init();
|
||||
|
||||
|
||||
//=========================================================
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* PHPUnit data generator class
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
class phpunit_data_generator {
|
||||
protected $usercounter = 0;
|
||||
protected $categorycount = 0;
|
||||
protected $coursecount = 0;
|
||||
protected $blockcount = 0;
|
||||
protected $modulecount = 0;
|
||||
|
||||
/**
|
||||
* To be called from data reset code only,
|
||||
* do not use in tests.
|
||||
* @return void
|
||||
*/
|
||||
public function reset() {
|
||||
$this->usercounter = 0;
|
||||
$this->categorycount = 0;
|
||||
$this->coursecount = 0;
|
||||
$this->blockcount = 0;
|
||||
$this->modulecount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test user
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass
|
||||
*/
|
||||
public function create_user($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$this->usercounter++;
|
||||
$i = $this->usercounter;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['auth'])) {
|
||||
$record['auth'] = 'manual';
|
||||
}
|
||||
|
||||
if (!isset($record['firstname'])) {
|
||||
$record['firstname'] = 'Firstname'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['lastname'])) {
|
||||
$record['lastname'] = 'Lastname'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['username'])) {
|
||||
$record['username'] = 'username'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['password'])) {
|
||||
$record['password'] = 'lala';
|
||||
}
|
||||
|
||||
if (!isset($record['email'])) {
|
||||
$record['email'] = $record['username'].'@example.com';
|
||||
}
|
||||
|
||||
if (!isset($record['confirmed'])) {
|
||||
$record['confirmed'] = 1;
|
||||
}
|
||||
|
||||
if (!isset($record['mnethostid'])) {
|
||||
$record['mnethostid'] = $CFG->mnet_localhost_id;
|
||||
}
|
||||
|
||||
if (!isset($record['lang'])) {
|
||||
$record['lang'] = 'en';
|
||||
}
|
||||
|
||||
if (!isset($record['maildisplay'])) {
|
||||
$record['maildisplay'] = 1;
|
||||
}
|
||||
|
||||
if (!isset($record['deleted'])) {
|
||||
$record['deleted'] = 0;
|
||||
}
|
||||
|
||||
$record['timecreated'] = time();
|
||||
$record['timemodified'] = $record['timecreated'];
|
||||
$record['lastip'] = '0.0.0.0';
|
||||
|
||||
$record['password'] = hash_internal_user_password($record['password']);
|
||||
|
||||
if ($record['deleted']) {
|
||||
$delname = $record['email'].'.'.time();
|
||||
while ($DB->record_exists('user', array('username'=>$delname))) {
|
||||
$delname++;
|
||||
}
|
||||
$record['idnumber'] = '';
|
||||
$record['email'] = md5($record['username']);
|
||||
$record['username'] = $delname;
|
||||
}
|
||||
|
||||
$userid = $DB->insert_record('user', $record);
|
||||
if (!$record['deleted']) {
|
||||
context_user::instance($userid);
|
||||
}
|
||||
|
||||
return $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test course category
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass
|
||||
*/
|
||||
function create_category($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$this->categorycount++;
|
||||
$i = $this->categorycount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'Course category '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = 'Test course category '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['description'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if (!isset($record['parent'])) {
|
||||
$record['descriptionformat'] = 0;
|
||||
}
|
||||
|
||||
if ($record['parent'] == 0) {
|
||||
$parent = new stdClass();
|
||||
$parent->path = '';
|
||||
$parent->depth = 0;
|
||||
} else {
|
||||
$parent = $DB->get_record('course_categories', array('id'=>$record['parent']), '*', MUST_EXIST);
|
||||
}
|
||||
$record['depth'] = $parent->depth+1;
|
||||
|
||||
$record['sortorder'] = 0;
|
||||
$record['timemodified'] = time();
|
||||
$record['timecreated'] = $record['timemodified'];
|
||||
|
||||
$catid = $DB->insert_record('course_categories', $record);
|
||||
$path = $parent->path . '/' . $catid;
|
||||
$DB->set_field('course_categories', 'path', $path, array('id'=>$catid));
|
||||
context_coursecat::instance($catid);
|
||||
|
||||
fix_course_sortorder();
|
||||
|
||||
return $DB->get_record('course_categories', array('id'=>$catid), '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test course
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass
|
||||
*/
|
||||
function create_course($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$this->coursecount++;
|
||||
$i = $this->coursecount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['fullname'])) {
|
||||
$record['fullname'] = 'Test course '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['shortname'])) {
|
||||
$record['shortname'] = 'tc_'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['format'])) {
|
||||
$record['format'] = 'topics';
|
||||
}
|
||||
|
||||
if (!isset($record['newsitems'])) {
|
||||
$record['newsitems'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['numsections'])) {
|
||||
$record['numsections'] = 5;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = 'Test course '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['description'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if (!isset($record['category'])) {
|
||||
$record['category'] = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
|
||||
}
|
||||
|
||||
$course = create_course((object)$record);
|
||||
context_course::instance($course->id);
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test block
|
||||
* @param string $blockname
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass
|
||||
*/
|
||||
public function create_block($blockname, $record=null, array $options=null) {
|
||||
global $DB;
|
||||
|
||||
$this->blockcount++;
|
||||
$i = $this->blockcount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
$record['blockname'] = $blockname;
|
||||
|
||||
//TODO: use block callbacks
|
||||
|
||||
if (!isset($record['parentcontextid'])) {
|
||||
$record['parentcontextid'] = context_system::instance()->id;
|
||||
}
|
||||
|
||||
if (!isset($record['showinsubcontexts'])) {
|
||||
$record['showinsubcontexts'] = 1;
|
||||
}
|
||||
|
||||
if (!isset($record['pagetypepattern'])) {
|
||||
$record['pagetypepattern'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['subpagepattern'])) {
|
||||
$record['subpagepattern'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['defaultweight'])) {
|
||||
$record['defaultweight'] = '';
|
||||
}
|
||||
|
||||
$biid = $DB->insert_record('block_instances', $record);
|
||||
context_block::instance($biid);
|
||||
|
||||
return $DB->get_record('block_instances', array('id'=>$biid), '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test module
|
||||
* @param string $modulename
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass
|
||||
*/
|
||||
public function create_module($modulename, $record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$this->modulecount++;
|
||||
$i = $this->modulecount;
|
||||
|
||||
$record = (array)$record;
|
||||
$options = (array)$options;
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = get_string('pluginname', $modulename).' '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['intro'])) {
|
||||
$record['intro'] = 'Test module '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['introformat'])) {
|
||||
$record['introformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if (!isset($options['section'])) {
|
||||
$options['section'] = 1;
|
||||
}
|
||||
|
||||
//TODO: use module callbacks
|
||||
|
||||
if ($modulename === 'page') {
|
||||
if (!isset($record['content'])) {
|
||||
$record['content'] = 'Test page content';
|
||||
}
|
||||
if (!isset($record['contentformat'])) {
|
||||
$record['contentformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
} else {
|
||||
error('TODO: only mod_page is supported in data generator for now');
|
||||
}
|
||||
|
||||
$id = $DB->insert_record($modulename, $record);
|
||||
|
||||
$cm = new stdClass();
|
||||
$cm->course = $record['course'];
|
||||
$cm->module = $DB->get_field('modules', 'id', array('name'=>$modulename));
|
||||
$cm->section = $options['section'];
|
||||
$cm->instance = $id;
|
||||
$cm->id = $DB->insert_record('course_modules', $cm);
|
||||
|
||||
$cm->coursemodule = $cm->id;
|
||||
add_mod_to_section($cm);
|
||||
|
||||
context_module::instance($cm->id);
|
||||
|
||||
$instance = $DB->get_record($modulename, array('id'=>$id), '*', MUST_EXIST);
|
||||
$instance->cmid = $cm->id;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
+394
-95
@@ -48,6 +48,29 @@ class phpunit_util {
|
||||
*/
|
||||
protected static $globals = array();
|
||||
|
||||
/**
|
||||
* @var int last value of db writes counter, used for db resetting
|
||||
*/
|
||||
protected static $lastdbwrites = null;
|
||||
|
||||
/**
|
||||
* @var phpunit_data_generator
|
||||
*/
|
||||
protected static $generator = null;
|
||||
|
||||
/**
|
||||
* Get data generator
|
||||
* @static
|
||||
* @return phpunit_data_generator
|
||||
*/
|
||||
public static function get_data_generator() {
|
||||
if (is_null(self::$generator)) {
|
||||
require_once(__DIR__.'/generatorlib.php');
|
||||
self::$generator = new phpunit_data_generator();
|
||||
}
|
||||
return self::$generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns contents of all tables right after installation.
|
||||
* @static
|
||||
@@ -56,6 +79,11 @@ class phpunit_util {
|
||||
protected static function get_tabledata() {
|
||||
global $CFG;
|
||||
|
||||
if (!file_exists("$CFG->dataroot/phpunit/tabledata.ser")) {
|
||||
// not initialised yet
|
||||
return array();
|
||||
}
|
||||
|
||||
if (!isset(self::$tabledata)) {
|
||||
$data = file_get_contents("$CFG->dataroot/phpunit/tabledata.ser");
|
||||
self::$tabledata = unserialize($data);
|
||||
@@ -69,35 +97,57 @@ class phpunit_util {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise CFG using data from fresh new install.
|
||||
* Reset all database tables to default values.
|
||||
* @static
|
||||
* @param bool $logchanges
|
||||
* @param null|PHPUnit_Framework_TestCase $caller
|
||||
* @return bool true if reset done, false if skipped
|
||||
*/
|
||||
public static function initialise_cfg() {
|
||||
global $CFG, $DB;
|
||||
public static function reset_database($logchanges = false, PHPUnit_Framework_TestCase $caller = null) {
|
||||
global $DB;
|
||||
|
||||
if (!file_exists("$CFG->dataroot/phpunit/tabledata.ser")) {
|
||||
// most probably PHPUnit CLI installer
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$DB->get_manager()->table_exists('config') or !$DB->count_records('config')) {
|
||||
@unlink("$CFG->dataroot/phpunit/tabledata.ser");
|
||||
@unlink("$CFG->dataroot/phpunit/versionshash.txt");
|
||||
self::$tabledata = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$data = self::get_tabledata();
|
||||
|
||||
foreach($data['config'] as $record) {
|
||||
$name = $record->name;
|
||||
$value = $record->value;
|
||||
if (property_exists($CFG, $name)) {
|
||||
// config.php settings always take precedence
|
||||
continue;
|
||||
if ($logchanges) {
|
||||
if (self::$lastdbwrites != $DB->perf_get_writes()) {
|
||||
if ($caller) {
|
||||
$where = ' in testcase: '.get_class($caller).'->'.$caller->getName(true);
|
||||
} else {
|
||||
$where = '';
|
||||
}
|
||||
error_log('warning: unexpected database modification, resetting DB state'.$where);
|
||||
}
|
||||
$CFG->{$name} = $value;
|
||||
}
|
||||
|
||||
$tables = $DB->get_tables(false);
|
||||
if (!$tables or empty($tables['config'])) {
|
||||
// not installed yet
|
||||
return;
|
||||
}
|
||||
|
||||
$dbreset = false;
|
||||
if (is_null(self::$lastdbwrites) or self::$lastdbwrites != $DB->perf_get_writes()) {
|
||||
if ($data = self::get_tabledata()) {
|
||||
$trans = $DB->start_delegated_transaction(); // faster and safer
|
||||
foreach ($data as $table=>$records) {
|
||||
$DB->delete_records($table, array());
|
||||
$resetseq = null;
|
||||
foreach ($records as $record) {
|
||||
if (is_null($resetseq)) {
|
||||
$resetseq = property_exists($record, 'id');
|
||||
}
|
||||
$DB->import_record($table, $record, false, true);
|
||||
}
|
||||
if ($resetseq === true) {
|
||||
$DB->get_manager()->reset_sequence($table, true);
|
||||
}
|
||||
}
|
||||
$trans->allow_commit();
|
||||
$dbreset = true;
|
||||
}
|
||||
}
|
||||
|
||||
self::$lastdbwrites = $DB->perf_get_writes();
|
||||
|
||||
return $dbreset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,47 +155,101 @@ class phpunit_util {
|
||||
*
|
||||
* Note: this is relatively slow (cca 2 seconds for pg and 7 for mysql) - please use with care!
|
||||
*
|
||||
* @param bool $logchanges log changes in global state and database in error log
|
||||
* @param PHPUnit_Framework_TestCase $caller caller object, used for logging only
|
||||
* @return void
|
||||
* @static
|
||||
*/
|
||||
public static function reset_all_data() {
|
||||
global $DB, $CFG;
|
||||
public static function reset_all_data($logchanges = false, PHPUnit_Framework_TestCase $caller = null) {
|
||||
global $DB, $CFG, $USER;
|
||||
|
||||
$data = self::get_tabledata();
|
||||
$dbreset = self::reset_database($logchanges, $caller);
|
||||
|
||||
$trans = $DB->start_delegated_transaction(); // faster and safer
|
||||
foreach ($data as $table=>$records) {
|
||||
$DB->delete_records($table, array());
|
||||
$resetseq = null;
|
||||
foreach ($records as $record) {
|
||||
if (is_null($resetseq)) {
|
||||
$resetseq = property_exists($record, 'id');
|
||||
}
|
||||
$DB->import_record($table, $record, false, true);
|
||||
if ($logchanges) {
|
||||
if ($caller) {
|
||||
$where = ' in testcase: '.get_class($caller).'->'.$caller->getName(true);
|
||||
} else {
|
||||
$where = '';
|
||||
}
|
||||
if ($resetseq === true) {
|
||||
$DB->get_manager()->reset_sequence($table, true);
|
||||
|
||||
$oldcfg = self::get_global_backup('CFG');
|
||||
foreach($CFG as $k=>$v) {
|
||||
if (!property_exists($oldcfg, $k)) {
|
||||
error_log('warning: unexpected new $CFG->'.$k.' value'.$where);
|
||||
} else if ($oldcfg->$k !== $CFG->$k) {
|
||||
error_log('warning: unexpected change of $CFG->'.$k.' value'.$where);
|
||||
}
|
||||
unset($oldcfg->$k);
|
||||
|
||||
}
|
||||
if ($oldcfg) {
|
||||
foreach($oldcfg as $k=>$v) {
|
||||
error_log('warning: unexpected removal of $CFG->'.$k.$where);
|
||||
}
|
||||
}
|
||||
|
||||
if ($USER->id != 0) {
|
||||
error_log('warning: unexpected change of $USER'.$where);
|
||||
}
|
||||
}
|
||||
$trans->allow_commit();
|
||||
|
||||
purge_all_caches();
|
||||
// restore original config
|
||||
$CFG = self::get_global_backup('CFG');
|
||||
|
||||
// set fresh new user
|
||||
$user = new stdClass();
|
||||
$user->id = 0;
|
||||
$user->mnet = 0;
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
session_set_user($user);
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
|
||||
// reset all static caches
|
||||
accesslib_clear_all_caches(true);
|
||||
get_string_manager()->reset_caches();
|
||||
//TODO: add more resets here and probably refactor them to new core function
|
||||
|
||||
// purge dataroot
|
||||
$handle = opendir($CFG->dataroot);
|
||||
$skip = array('.', '..', 'phpunittestdir.txt', 'phpunit', '.htaccess');
|
||||
while (false !== ($item = readdir($handle))) {
|
||||
if (in_array($item, $skip)) {
|
||||
continue;
|
||||
}
|
||||
if (is_dir("$CFG->dataroot/$item")) {
|
||||
remove_dir("$CFG->dataroot/$item", false);
|
||||
} else {
|
||||
unlink("$CFG->dataroot/$item");
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
make_temp_directory('');
|
||||
make_cache_directory('');
|
||||
make_cache_directory('htmlpurifier');
|
||||
|
||||
// restore original config once more in case resetting of caches changes CFG
|
||||
$CFG = self::get_global_backup('CFG');
|
||||
|
||||
// remember db writes
|
||||
self::$lastdbwrites = $DB->perf_get_writes();
|
||||
|
||||
// inform data generator
|
||||
self::get_data_generator()->reset();
|
||||
|
||||
// fix PHP settings
|
||||
error_reporting($CFG->debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called during bootstrap only!
|
||||
* @static
|
||||
*/
|
||||
public static function init_globals() {
|
||||
public static function bootstrap_init() {
|
||||
global $CFG;
|
||||
|
||||
// backup the globals
|
||||
self::$globals['CFG'] = clone($CFG);
|
||||
|
||||
// refresh data in all tables, clear caches, etc.
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +282,7 @@ class phpunit_util {
|
||||
|
||||
if (!file_exists("$CFG->dataroot/phpunittestdir.txt")) {
|
||||
// this is already tested in bootstrap script,
|
||||
// but anway presence of this file means the dataroot is for testing
|
||||
// but anyway presence of this file means the dataroot is for testing
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -199,41 +303,41 @@ class phpunit_util {
|
||||
* Is this site initialised to run unit tests?
|
||||
*
|
||||
* @static
|
||||
* @return bool
|
||||
* @return int error code, 0 means ok
|
||||
*/
|
||||
public static function is_testing_ready() {
|
||||
public static function testing_ready_problem() {
|
||||
global $DB, $CFG;
|
||||
|
||||
if (!self::is_test_site()) {
|
||||
return false;
|
||||
return 131;
|
||||
}
|
||||
|
||||
$tables = $DB->get_tables(true);
|
||||
|
||||
if (!$tables) {
|
||||
return false;
|
||||
return 132;
|
||||
}
|
||||
|
||||
if (!get_config('core', 'phpunittest')) {
|
||||
return false;
|
||||
return 131;
|
||||
}
|
||||
|
||||
if (!file_exists("$CFG->dataroot/phpunit/tabledata.ser")) {
|
||||
return false;
|
||||
return 131;
|
||||
}
|
||||
|
||||
if (!file_exists("$CFG->dataroot/phpunit/versionshash.txt")) {
|
||||
return false;
|
||||
return 131;
|
||||
}
|
||||
|
||||
$hash = phpunit_util::get_version_hash();
|
||||
$oldhash = file_get_contents("$CFG->dataroot/phpunit/versionshash.txt");
|
||||
|
||||
if ($hash !== $oldhash) {
|
||||
return false;
|
||||
return 133;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,8 +400,9 @@ class phpunit_util {
|
||||
|
||||
install_cli_database($options, false);
|
||||
|
||||
// just in case remove admin password so that normal login is not possible
|
||||
$DB->set_field('user', 'password', 'not cached', array('username' => 'admin'));
|
||||
// install timezone info
|
||||
$timezones = get_records_csv($CFG->libdir.'/timezone.txt', 'timezone');
|
||||
update_timezone_records($timezones);
|
||||
|
||||
// add test db flag
|
||||
set_config('phpunittest', 'phpunittest');
|
||||
@@ -319,7 +424,7 @@ class phpunit_util {
|
||||
}
|
||||
|
||||
/**
|
||||
* Culculate unique version hash for all available plugins and core.
|
||||
* Calculate unique version hash for all available plugins and core.
|
||||
* @static
|
||||
* @return string sha1 hash
|
||||
*/
|
||||
@@ -372,11 +477,9 @@ class phpunit_util {
|
||||
global $CFG;
|
||||
|
||||
$template = '
|
||||
<testsuites>
|
||||
<testsuite name="@component@">
|
||||
<directory suffix="_test.php">@dir@</directory>
|
||||
</testsuite>
|
||||
</testsuites>';
|
||||
</testsuite>';
|
||||
$data = file_get_contents("$CFG->dirroot/phpunit.xml.dist");
|
||||
|
||||
$suites = '';
|
||||
@@ -427,6 +530,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @deprecated since 2.3
|
||||
* @param bool $expected
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function expectException($expected, $message = '') {
|
||||
// use phpdocs: @expectedException ExceptionClassName
|
||||
@@ -440,6 +544,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @deprecated since 2.3
|
||||
* @param bool $expected
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function expectError($expected = false, $message = '') {
|
||||
// not available in PHPUnit
|
||||
@@ -454,6 +559,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @static
|
||||
* @param mixed $actual
|
||||
* @param string $messages
|
||||
* @return void
|
||||
*/
|
||||
public static function assertTrue($actual, $messages = '') {
|
||||
parent::assertTrue((bool)$actual, $messages);
|
||||
@@ -464,6 +570,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @static
|
||||
* @param mixed $actual
|
||||
* @param string $messages
|
||||
* @return void
|
||||
*/
|
||||
public static function assertFalse($actual, $messages = '') {
|
||||
parent::assertFalse((bool)$actual, $messages);
|
||||
@@ -475,6 +582,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertEqual($expected, $actual, $message = '') {
|
||||
parent::assertEquals($expected, $actual, $message);
|
||||
@@ -486,6 +594,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertNotEqual($expected, $actual, $message = '') {
|
||||
parent::assertNotEquals($expected, $actual, $message);
|
||||
@@ -497,6 +606,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertIdentical($expected, $actual, $message = '') {
|
||||
parent::assertSame($expected, $actual, $message);
|
||||
@@ -508,6 +618,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertNotIdentical($expected, $actual, $message = '') {
|
||||
parent::assertNotSame($expected, $actual, $message);
|
||||
@@ -519,6 +630,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
* @param mixed $actual
|
||||
* @param mixed $expected
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertIsA($actual, $expected, $message = '') {
|
||||
parent::assertInstanceOf($expected, $actual, $message);
|
||||
@@ -529,7 +641,7 @@ class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* The simplest PHPUnit test case customised for Moodle
|
||||
*
|
||||
* This test case does not modify database or any globals.
|
||||
* It is intended for isolated tests that do not modify database or any globals.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
@@ -551,7 +663,44 @@ class basic_testcase extends PHPUnit_Framework_TestCase {
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(false);
|
||||
$this->setInIsolation(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the bare test sequence and log any changes in global state or database.
|
||||
* @return void
|
||||
*/
|
||||
public function runBare() {
|
||||
parent::runBare();
|
||||
phpunit_util::reset_all_data(true, $this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Advanced PHPUnit test case customised for Moodle.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class advanced_testcase extends PHPUnit_Framework_TestCase {
|
||||
/** @var bool automatically reset everything? */
|
||||
protected $resetAfterTest;
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
public function __construct($name = NULL, array $data = array(), $dataName = '') {
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -559,43 +708,193 @@ class basic_testcase extends PHPUnit_Framework_TestCase {
|
||||
* @return void
|
||||
*/
|
||||
public function runBare() {
|
||||
global $CFG, $USER, $DB;
|
||||
|
||||
$dbwrites = $DB->perf_get_writes();
|
||||
$this->resetAfterTest = null;
|
||||
|
||||
parent::runBare();
|
||||
|
||||
$oldcfg = phpunit_util::get_global_backup('CFG');
|
||||
foreach($CFG as $k=>$v) {
|
||||
if (!property_exists($oldcfg, $k)) {
|
||||
unset($CFG->$k);
|
||||
error_log('warning: unexpected new $CFG->'.$k.' value in testcase: '.get_class($this).'->'.$this->getName(true));
|
||||
} else if ($oldcfg->$k !== $CFG->$k) {
|
||||
$CFG->$k = $oldcfg->$k;
|
||||
error_log('warning: unexpected change of $CFG->'.$k.' value in testcase: '.get_class($this).'->'.$this->getName(true));
|
||||
}
|
||||
unset($oldcfg->$k);
|
||||
|
||||
}
|
||||
if ($oldcfg) {
|
||||
foreach($oldcfg as $k=>$v) {
|
||||
$CFG->$k = $v;
|
||||
error_log('warning: unexpected removal of $CFG->'.$k.' in testcase: '.get_class($this).'->'.$this->getName(true));
|
||||
}
|
||||
if ($this->resetAfterTest === true) {
|
||||
self::resetAllData();
|
||||
} else if ($this->resetAfterTest === false) {
|
||||
// keep all data untouched for other tests
|
||||
} else {
|
||||
// reset but log what changed
|
||||
phpunit_util::reset_all_data(true, $this);
|
||||
}
|
||||
|
||||
if ($USER->id != 0) {
|
||||
error_log('warning: unexpected change of $USER in testcase: '.get_class($this).'->'.$this->getName(true));
|
||||
$USER = new stdClass();
|
||||
$USER->id = 0;
|
||||
}
|
||||
|
||||
if ($dbwrites != $DB->perf_get_writes()) {
|
||||
//TODO: find out what was changed exactly
|
||||
error_log('warning: unexpected database modification, resetting DB state in testcase: '.get_class($this).'->'.$this->getName(true));
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
|
||||
//TODO: somehow find out if there are changes in dataroot
|
||||
$this->resetAfterTest = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset everything after current test.
|
||||
* @param bool $reset true means reset state back, false means keep all data for the next test,
|
||||
* null means reset state and show warnings if anything changed
|
||||
* @return void
|
||||
*/
|
||||
public function resetAfterTest($reset = true) {
|
||||
$this->resetAfterTest = $reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup after all tests are executed.
|
||||
*
|
||||
* Note: do not forget to call this if overridden...
|
||||
*
|
||||
* @static
|
||||
* @return void
|
||||
*/
|
||||
public static function tearDownAfterClass() {
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all database tables, restore global state and clear caches and optionally purge dataroot dir.
|
||||
* @static
|
||||
* @return void
|
||||
*/
|
||||
public static function resetAllData() {
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data generator
|
||||
* @static
|
||||
* @return phpunit_data_generator
|
||||
*/
|
||||
public static function getDataGenerator() {
|
||||
return phpunit_util::get_data_generator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively visit all the files in the source tree. Calls the callback
|
||||
* function with the pathname of each file found.
|
||||
*
|
||||
* @param $path the folder to start searching from.
|
||||
* @param $callback the function to call with the name of each file found.
|
||||
* @param $fileregexp a regexp used to filter the search (optional).
|
||||
* @param $exclude If true, pathnames that match the regexp will be ingored. If false,
|
||||
* only files that match the regexp will be included. (default false).
|
||||
* @param array $ignorefolders will not go into any of these folders (optional).
|
||||
* @return void
|
||||
*/
|
||||
public function recurseFolders($path, $callback, $fileregexp = '/.*/', $exclude = false, $ignorefolders = array()) {
|
||||
$files = scandir($path);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$filepath = $path .'/'. $file;
|
||||
if (strpos($file, '.') === 0) {
|
||||
/// Don't check hidden files.
|
||||
continue;
|
||||
} else if (is_dir($filepath)) {
|
||||
if (!in_array($filepath, $ignorefolders)) {
|
||||
$this->recurseFolders($filepath, $callback, $fileregexp, $exclude, $ignorefolders);
|
||||
}
|
||||
} else if ($exclude xor preg_match($fileregexp, $filepath)) {
|
||||
$this->$callback($filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test integration of PHPUnit and custom Moodle hacks.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class database_driver_testcase extends PHPUnit_Framework_TestCase {
|
||||
protected static $extradb = null;
|
||||
protected $skipped = false;
|
||||
|
||||
/** @var moodle_database */
|
||||
protected $tdb;
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
public function __construct($name = NULL, array $data = array(), $dataName = '') {
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(false);
|
||||
}
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
global $CFG;
|
||||
|
||||
if (!defined('PHPUNIT_TEST_DRIVER')) {
|
||||
// use normal $DB
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER])) {
|
||||
throw new exception('Can not find driver configuration options with index: '.PHPUNIT_TEST_DRIVER);
|
||||
}
|
||||
|
||||
$dblibrary = empty($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dblibrary']) ? 'native' : $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dblibrary'];
|
||||
$dbtype = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbtype'];
|
||||
$dbhost = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbhost'];
|
||||
$dbname = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbname'];
|
||||
$dbuser = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbuser'];
|
||||
$dbpass = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbpass'];
|
||||
$prefix = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['prefix'];
|
||||
$dboptions = empty($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dboptions']) ? array() : $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dboptions'];
|
||||
|
||||
$classname = "{$dbtype}_{$dblibrary}_moodle_database";
|
||||
require_once("$CFG->libdir/dml/$classname.php");
|
||||
$d = new $classname();
|
||||
if (!$d->driver_installed()) {
|
||||
throw new exception('Database driver for '.$classname.' is not installed');
|
||||
}
|
||||
|
||||
$d->connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, $dboptions);
|
||||
|
||||
self::$extradb = $d;
|
||||
}
|
||||
|
||||
public function getStatus() {
|
||||
if ($this->skipped) {
|
||||
// fake the status
|
||||
return PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
|
||||
} else {
|
||||
return parent::getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
global $DB;
|
||||
|
||||
if (self::$extradb) {
|
||||
$this->tdb = self::$extradb;
|
||||
} else {
|
||||
$this->tdb = $DB;
|
||||
}
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
// delete all test tables
|
||||
$dbman = $this->tdb->get_manager();
|
||||
$tables = $this->tdb->get_tables(false);
|
||||
foreach($tables as $tablename) {
|
||||
if (strpos($tablename, 'test_table') === 0) {
|
||||
$table = new xmldb_table($tablename);
|
||||
$dbman->drop_table($table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass() {
|
||||
if (self::$extradb) {
|
||||
self::$extradb->dispose();
|
||||
self::$extradb = null;
|
||||
}
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ Test execution
|
||||
How to add more tests
|
||||
---------------------
|
||||
1. create `tests` directory in any plugin
|
||||
2. add `*_test.php` files with custom class that extends `basic_testcase`
|
||||
2. add `*_test.php` files with custom class that extends `basic_testcase` or `advanced_testcase`
|
||||
3. manually add all core unit test locations to `phpunit.xml.dist`
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ FAQs
|
||||
|
||||
TODO
|
||||
----
|
||||
* stage 2 - implement advanced_testcase - support for database modifications, object generators, automatic rollback of db, globals and dataroot
|
||||
* stage 3 - mocking and other advanced features, add support for execution of functional DB tests for different engines together (new options in phpunit.xml)
|
||||
* other - support for execution of tests and cli/util.php from web UI (to be implemented via shell execution), shell script that prepares everything for the first execution
|
||||
* add plugin callbacks to data generator
|
||||
* convert remaining tests
|
||||
* improve performance
|
||||
* hide old SimpleTests and FUnctional DB tests in UI
|
||||
* shell script that prepares everything for the first execution
|
||||
* optionally support for execution of tests and cli/util.php from web UI (to be implemented via shell execution)
|
||||
|
||||
+1
-1
@@ -479,7 +479,7 @@ class plugin_manager {
|
||||
|
||||
'tool' => array(
|
||||
'bloglevelupgrade', 'capability', 'customlang', 'dbtransfer', 'generator',
|
||||
'health', 'innodb', 'langimport', 'multilangupgrade', 'profiling',
|
||||
'health', 'innodb', 'langimport', 'multilangupgrade', 'phpunit', 'profiling',
|
||||
'qeupgradehelper', 'replace', 'spamcleaner', 'timezoneimport', 'unittest',
|
||||
'uploaduser', 'unsuproles', 'xmldb'
|
||||
),
|
||||
|
||||
+21
-16
@@ -45,7 +45,7 @@
|
||||
global $CFG; // this should be done much earlier in config.php before creating new $CFG instance
|
||||
|
||||
if (!isset($CFG)) {
|
||||
if (defined('PHPUNITTEST') and PHPUNITTEST) {
|
||||
if (defined('PHPUNIT_TEST') and PHPUNIT_TEST) {
|
||||
echo('There is a missing "global $CFG;" at the beginning of the config.php file.'."\n");
|
||||
exit(1);
|
||||
} else {
|
||||
@@ -134,8 +134,8 @@ if (!defined('NO_OUTPUT_BUFFERING')) {
|
||||
}
|
||||
|
||||
// PHPUnit tests need custom init
|
||||
if (!defined('PHPUNITTEST')) {
|
||||
define('PHPUNITTEST', false);
|
||||
if (!defined('PHPUNIT_TEST')) {
|
||||
define('PHPUNIT_TEST', false);
|
||||
}
|
||||
|
||||
// Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
|
||||
@@ -398,11 +398,13 @@ init_performance_info();
|
||||
$OUTPUT = new bootstrap_renderer();
|
||||
|
||||
// set handler for uncaught exceptions - equivalent to print_error() call
|
||||
set_exception_handler('default_exception_handler');
|
||||
set_error_handler('default_error_handler', E_ALL | E_STRICT);
|
||||
if (!PHPUNIT_TEST or PHPUNIT_UTIL) {
|
||||
set_exception_handler('default_exception_handler');
|
||||
set_error_handler('default_error_handler', E_ALL | E_STRICT);
|
||||
}
|
||||
|
||||
// If there are any errors in the standard libraries we want to know!
|
||||
error_reporting(E_ALL);
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
// Just say no to link prefetching (Moz prefetching, Google Web Accelerator, others)
|
||||
// http://www.google.com/webmasters/faq.html#prefetchblock
|
||||
@@ -461,20 +463,21 @@ setup_validate_php_configuration();
|
||||
// Connect to the database
|
||||
setup_DB();
|
||||
|
||||
// reset DB tables
|
||||
if (PHPUNIT_TEST and !PHPUNIT_UTIL) {
|
||||
phpunit_util::reset_database();
|
||||
}
|
||||
|
||||
// Disable errors for now - needed for installation when debug enabled in config.php
|
||||
if (isset($CFG->debug)) {
|
||||
$originalconfigdebug = $CFG->debug;
|
||||
unset($CFG->debug);
|
||||
} else {
|
||||
$originalconfigdebug = -1;
|
||||
$originalconfigdebug = null;
|
||||
}
|
||||
|
||||
// Load up any configuration from the config table
|
||||
if (PHPUNITTEST) {
|
||||
phpunit_util::initialise_cfg();
|
||||
} else {
|
||||
initialise_cfg();
|
||||
}
|
||||
initialise_cfg();
|
||||
|
||||
// Verify upgrade is not running unless we are in a script that needs to execute in any case
|
||||
if (!defined('NO_UPGRADE_CHECK') and isset($CFG->upgraderunning)) {
|
||||
@@ -495,7 +498,7 @@ if (isset($CFG->debug)) {
|
||||
$originaldatabasedebug = $CFG->debug;
|
||||
unset($CFG->debug);
|
||||
} else {
|
||||
$originaldatabasedebug = -1;
|
||||
$originaldatabasedebug = null;
|
||||
}
|
||||
|
||||
// enable circular reference collector in PHP 5.3,
|
||||
@@ -510,12 +513,12 @@ if (function_exists('register_shutdown_function')) {
|
||||
}
|
||||
|
||||
// Set error reporting back to normal
|
||||
if ($originaldatabasedebug == -1) {
|
||||
if ($originaldatabasedebug === null) {
|
||||
$CFG->debug = DEBUG_MINIMAL;
|
||||
} else {
|
||||
$CFG->debug = $originaldatabasedebug;
|
||||
}
|
||||
if ($originalconfigdebug !== -1) {
|
||||
if ($originalconfigdebug !== null) {
|
||||
$CFG->debug = $originalconfigdebug;
|
||||
}
|
||||
unset($originalconfigdebug);
|
||||
@@ -823,7 +826,9 @@ if (!empty($CFG->customscripts)) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((CLI_SCRIPT and !defined('WEB_CRON_EMULATED_CLI')) or PHPUNITTEST) {
|
||||
if (PHPUNIT_TEST) {
|
||||
// no ip blocking, these are CLI only
|
||||
} else if (CLI_SCRIPT and !defined('WEB_CRON_EMULATED_CLI')) {
|
||||
// no ip blocking
|
||||
} else if (!empty($CFG->allowbeforeblock)) { // allowed list processed before blocked list?
|
||||
// in this case, ip in allowed list will be performed first
|
||||
|
||||
@@ -141,6 +141,10 @@ class moodle_exception extends Exception {
|
||||
$message = $module . '/' . $errorcode;
|
||||
}
|
||||
|
||||
if (PHPUNIT_TEST and $debuginfo) {
|
||||
$message = "$message ($debuginfo)";
|
||||
}
|
||||
|
||||
parent::__construct($message, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Unit tests for /lib/externallib.php.
|
||||
*
|
||||
* @package webservices
|
||||
* @copyright 2009 Pwetr Skoda
|
||||
* @copyright 2009 Petr Skoda
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,990 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Full functional accesslib test
|
||||
*
|
||||
* It is implemented as one test case because it would take hours
|
||||
* to prepare the fake test site for each test, at the same time
|
||||
* we have to work around multiple problems in UnitTestCaseUsingDatabase.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2011 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Context caching fixture
|
||||
*/
|
||||
class context_inspection extends context_helper {
|
||||
public static function test_context_cache_size() {
|
||||
return self::$cache_count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Functional test for accesslib.php
|
||||
*
|
||||
* Note: execution may take many minutes especially on slower servers.
|
||||
*/
|
||||
class accesslib_testcase extends advanced_testcase {
|
||||
|
||||
//TODO: add more tests for the remaining accesslib parts that were not touched by the refactoring in 2.2dev
|
||||
|
||||
/**
|
||||
* Verify comparison of context instances in phpunit asserts
|
||||
* @return void
|
||||
*/
|
||||
public function test_context_comparisons() {
|
||||
$frontpagecontext1 = context_course::instance(SITEID);
|
||||
context_helper::reset_caches();
|
||||
$frontpagecontext2 = context_course::instance(SITEID);
|
||||
$this->assertEquals($frontpagecontext1, $frontpagecontext2);
|
||||
|
||||
$user1 = context_user::instance(1);
|
||||
$user2 = context_user::instance(2);
|
||||
$this->assertNotEquals($user1, $user2);
|
||||
}
|
||||
|
||||
/**
|
||||
* A small functional test of accesslib functions and classes.
|
||||
* @return void
|
||||
*/
|
||||
public function test_everything_in_accesslib() {
|
||||
global $USER, $SITE, $CFG, $DB, $ACCESSLIB_PRIVATE;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
// Fill the site with some real data
|
||||
$testcategories = array();
|
||||
$testcourses = array();
|
||||
$testpages = array();
|
||||
$testblocks = array();
|
||||
$allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id');
|
||||
|
||||
$systemcontext = context_system::instance();
|
||||
$frontpagecontext = context_course::instance(SITEID);
|
||||
|
||||
// Add block to system context
|
||||
$bi = $generator->create_block('online_users');
|
||||
context_block::instance($bi->id);
|
||||
$testblocks[] = $bi->id;
|
||||
|
||||
// Some users
|
||||
$testusers = array();
|
||||
for($i=0; $i<20; $i++) {
|
||||
$user = $generator->create_user();
|
||||
$testusers[$i] = $user->id;
|
||||
$usercontext = context_user::instance($user->id);
|
||||
|
||||
// Add block to user profile
|
||||
$bi = $generator->create_block('online_users', array('parentcontextid'=>$usercontext->id));
|
||||
$testblocks[] = $bi->id;
|
||||
}
|
||||
// Deleted user - should be ignored everywhere, can not have context
|
||||
$generator->create_user(array('deleted'=>1));
|
||||
|
||||
// Add block to frontpage
|
||||
$bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagecontext->id));
|
||||
$frontpageblockcontext = context_block::instance($bi->id);
|
||||
$testblocks[] = $bi->id;
|
||||
|
||||
// Add a resource to frontpage
|
||||
$page = $generator->create_module('page', array('course'=>$SITE->id));
|
||||
$testpages[] = $page->id;
|
||||
$frontpagepagecontext = context_module::instance($page->cmid);
|
||||
|
||||
// Add block to frontpage resource
|
||||
$bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagepagecontext->id));
|
||||
$frontpagepageblockcontext = context_block::instance($bi->id);
|
||||
$testblocks[] = $bi->id;
|
||||
|
||||
// Some nested course categories with courses
|
||||
$manualenrol = enrol_get_plugin('manual');
|
||||
$parentcat = 0;
|
||||
for($i=0; $i<5; $i++) {
|
||||
$cat = $generator->create_category(array('parent'=>$parentcat));
|
||||
$testcategories[] = $cat->id;
|
||||
$catcontext = context_coursecat::instance($cat->id);
|
||||
$parentcat = $cat->id;
|
||||
|
||||
if ($i >=4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add resource to each category
|
||||
$bi = $generator->create_block('online_users', array('parentcontextid'=>$catcontext->id));
|
||||
context_block::instance($bi->id);
|
||||
|
||||
// Add a few courses to each category
|
||||
for($j=0; $j<6; $j++) {
|
||||
$course = $generator->create_course(array('category'=>$cat->id));
|
||||
$testcourses[] = $course->id;
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
|
||||
if ($j >= 5) {
|
||||
continue;
|
||||
}
|
||||
// Add manual enrol instance
|
||||
$manualenrol->add_default_instance($DB->get_record('course', array('id'=>$course->id)));
|
||||
|
||||
// Add block to each course
|
||||
$bi = $generator->create_block('online_users', array('parentcontextid'=>$coursecontext->id));
|
||||
$testblocks[] = $bi->id;
|
||||
|
||||
// Add a resource to each course
|
||||
$page = $generator->create_module('page', array('course'=>$course->id));
|
||||
$testpages[] = $page->id;
|
||||
$modcontext = context_module::instance($page->cmid);
|
||||
|
||||
// Add block to each module
|
||||
$bi = $generator->create_block('online_users', array('parentcontextid'=>$modcontext->id));
|
||||
$testblocks[] = $bi->id;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure all contexts were created properly
|
||||
$count = 1; //system
|
||||
$count += $DB->count_records('user', array('deleted'=>0));
|
||||
$count += $DB->count_records('course_categories');
|
||||
$count += $DB->count_records('course');
|
||||
$count += $DB->count_records('course_modules');
|
||||
$count += $DB->count_records('block_instances');
|
||||
$this->assertEquals($DB->count_records('context'), $count);
|
||||
$this->assertEquals($DB->count_records('context', array('depth'=>0)), 0);
|
||||
$this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0);
|
||||
|
||||
|
||||
// ====== context_helper::get_level_name() ================================
|
||||
|
||||
$levels = context_helper::get_all_levels();
|
||||
foreach ($levels as $level=>$classname) {
|
||||
$name = context_helper::get_level_name($level);
|
||||
$this->assertFalse(empty($name));
|
||||
}
|
||||
|
||||
|
||||
// ======= context::instance_by_id(), context_xxx::instance();
|
||||
|
||||
$context = context::instance_by_id($frontpagecontext->id);
|
||||
$this->assertSame($context->contextlevel, CONTEXT_COURSE);
|
||||
$this->assertFalse(context::instance_by_id(-1, IGNORE_MISSING));
|
||||
try {
|
||||
context::instance_by_id(-1);
|
||||
$this->fail('exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
$this->assertTrue(context_system::instance() instanceof context_system);
|
||||
$this->assertTrue(context_coursecat::instance($testcategories[0]) instanceof context_coursecat);
|
||||
$this->assertTrue(context_course::instance($testcourses[0]) instanceof context_course);
|
||||
$this->assertTrue(context_module::instance($testpages[0]) instanceof context_module);
|
||||
$this->assertTrue(context_block::instance($testblocks[0]) instanceof context_block);
|
||||
|
||||
$this->assertFalse(context_coursecat::instance(-1, IGNORE_MISSING));
|
||||
$this->assertFalse(context_course::instance(-1, IGNORE_MISSING));
|
||||
$this->assertFalse(context_module::instance(-1, IGNORE_MISSING));
|
||||
$this->assertFalse(context_block::instance(-1, IGNORE_MISSING));
|
||||
try {
|
||||
context_coursecat::instance(-1);
|
||||
$this->fail('exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
try {
|
||||
context_course::instance(-1);
|
||||
$this->fail('exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
try {
|
||||
context_module::instance(-1);
|
||||
$this->fail('exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
try {
|
||||
context_block::instance(-1);
|
||||
$this->fail('exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
|
||||
// ======= $context->get_url(), $context->get_context_name(), $context->get_capabilities() =========
|
||||
|
||||
$testcontexts = array();
|
||||
$testcontexts[CONTEXT_SYSTEM] = context_system::instance();
|
||||
$testcontexts[CONTEXT_COURSECAT] = context_coursecat::instance($testcategories[0]);
|
||||
$testcontexts[CONTEXT_COURSE] = context_course::instance($testcourses[0]);
|
||||
$testcontexts[CONTEXT_MODULE] = context_module::instance($testpages[0]);
|
||||
$testcontexts[CONTEXT_BLOCK] = context_block::instance($testblocks[0]);
|
||||
|
||||
foreach ($testcontexts as $context) {
|
||||
$name = $context->get_context_name(true, true);
|
||||
$this->assertFalse(empty($name));
|
||||
|
||||
$this->assertTrue($context->get_url() instanceof moodle_url);
|
||||
|
||||
$caps = $context->get_capabilities();
|
||||
$this->assertTrue(is_array($caps));
|
||||
foreach ($caps as $cap) {
|
||||
$cap = (array)$cap;
|
||||
$this->assertSame(array_keys($cap), array('id', 'name', 'captype', 'contextlevel', 'component', 'riskbitmask'));
|
||||
}
|
||||
}
|
||||
unset($testcontexts);
|
||||
|
||||
// ===== $context->get_course_context() =========================================
|
||||
|
||||
$this->assertFalse($systemcontext->get_course_context(false));
|
||||
try {
|
||||
$systemcontext->get_course_context();
|
||||
$this->fail('exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
$context = context_coursecat::instance($testcategories[0]);
|
||||
$this->assertFalse($context->get_course_context(false));
|
||||
try {
|
||||
$context->get_course_context();
|
||||
$this->fail('exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
$this->assertSame($frontpagecontext->get_course_context(true), $frontpagecontext);
|
||||
$this->assertSame($frontpagepagecontext->get_course_context(true), $frontpagecontext);
|
||||
$this->assertSame($frontpagepageblockcontext->get_course_context(true), $frontpagecontext);
|
||||
|
||||
|
||||
// ======= $context->get_parent_context(), $context->get_parent_contexts(), $context->get_parent_context_ids() =======
|
||||
|
||||
$userid = reset($testusers);
|
||||
$usercontext = context_user::instance($userid);
|
||||
$this->assertSame($usercontext->get_parent_context(), $systemcontext);
|
||||
$this->assertSame($usercontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext));
|
||||
$this->assertSame($usercontext->get_parent_contexts(true), array($usercontext->id=>$usercontext, $systemcontext->id=>$systemcontext));
|
||||
|
||||
$this->assertSame($systemcontext->get_parent_contexts(), array());
|
||||
$this->assertSame($systemcontext->get_parent_contexts(true), array($systemcontext->id=>$systemcontext));
|
||||
$this->assertSame($systemcontext->get_parent_context_ids(), array());
|
||||
$this->assertSame($systemcontext->get_parent_context_ids(true), array($systemcontext->id));
|
||||
|
||||
$this->assertSame($frontpagecontext->get_parent_context(), $systemcontext);
|
||||
$this->assertSame($frontpagecontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext));
|
||||
$this->assertSame($frontpagecontext->get_parent_contexts(true), array($frontpagecontext->id=>$frontpagecontext, $systemcontext->id=>$systemcontext));
|
||||
$this->assertSame($frontpagecontext->get_parent_context_ids(), array($systemcontext->id));
|
||||
$this->assertEquals($frontpagecontext->get_parent_context_ids(true), array($frontpagecontext->id, $systemcontext->id));
|
||||
|
||||
$this->assertSame($systemcontext->get_parent_context(), false);
|
||||
$frontpagecontext = context_course::instance($SITE->id);
|
||||
$parent = $systemcontext;
|
||||
foreach ($testcategories as $catid) {
|
||||
$catcontext = context_coursecat::instance($catid);
|
||||
$this->assertSame($catcontext->get_parent_context(), $parent);
|
||||
$parent = $catcontext;
|
||||
}
|
||||
$this->assertSame($frontpagepagecontext->get_parent_context(), $frontpagecontext);
|
||||
$this->assertSame($frontpageblockcontext->get_parent_context(), $frontpagecontext);
|
||||
$this->assertSame($frontpagepageblockcontext->get_parent_context(), $frontpagepagecontext);
|
||||
|
||||
|
||||
// ====== $context->get_child_contexts() ================================
|
||||
|
||||
$CFG->debug = 0;
|
||||
$children = $systemcontext->get_child_contexts();
|
||||
$CFG->debug = DEBUG_DEVELOPER;
|
||||
$this->assertEquals(count($children)+1, $DB->count_records('context'));
|
||||
|
||||
$context = context_coursecat::instance($testcategories[3]);
|
||||
$children = $context->get_child_contexts();
|
||||
$countcats = 0;
|
||||
$countcourses = 0;
|
||||
$countblocks = 0;
|
||||
foreach ($children as $child) {
|
||||
if ($child->contextlevel == CONTEXT_COURSECAT) {
|
||||
$countcats++;
|
||||
}
|
||||
if ($child->contextlevel == CONTEXT_COURSE) {
|
||||
$countcourses++;
|
||||
}
|
||||
if ($child->contextlevel == CONTEXT_BLOCK) {
|
||||
$countblocks++;
|
||||
}
|
||||
}
|
||||
$this->assertEquals(count($children), 8);
|
||||
$this->assertEquals($countcats, 1);
|
||||
$this->assertEquals($countcourses, 6);
|
||||
$this->assertEquals($countblocks, 1);
|
||||
|
||||
$context = context_course::instance($testcourses[2]);
|
||||
$children = $context->get_child_contexts();
|
||||
$this->assertEquals(count($children), 7); // depends on number of default blocks
|
||||
|
||||
$context = context_module::instance($testpages[3]);
|
||||
$children = $context->get_child_contexts();
|
||||
$this->assertEquals(count($children), 1);
|
||||
|
||||
$context = context_block::instance($testblocks[1]);
|
||||
$children = $context->get_child_contexts();
|
||||
$this->assertEquals(count($children), 0);
|
||||
|
||||
unset($children);
|
||||
unset($countcats);
|
||||
unset($countcourses);
|
||||
unset($countblocks);
|
||||
|
||||
|
||||
// ======= context_helper::reset_caches() ============================
|
||||
|
||||
context_helper::reset_caches();
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), 0);
|
||||
context_course::instance($SITE->id);
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), 1);
|
||||
|
||||
|
||||
// ======= context preloading ========================================
|
||||
|
||||
context_helper::reset_caches();
|
||||
$sql = "SELECT ".context_helper::get_preload_record_columns_sql('c')."
|
||||
FROM {context} c
|
||||
WHERE c.contextlevel <> ".CONTEXT_SYSTEM;
|
||||
$records = $DB->get_records_sql($sql);
|
||||
$firstrecord = reset($records);
|
||||
$columns = context_helper::get_preload_record_columns('c');
|
||||
$firstrecord = (array)$firstrecord;
|
||||
$this->assertSame(array_keys($firstrecord), array_values($columns));
|
||||
context_helper::reset_caches();
|
||||
foreach ($records as $record) {
|
||||
context_helper::preload_from_record($record);
|
||||
$this->assertEquals($record, new stdClass());
|
||||
}
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), count($records));
|
||||
unset($records);
|
||||
unset($columns);
|
||||
|
||||
context_helper::reset_caches();
|
||||
context_helper::preload_course($SITE->id);
|
||||
$this->assertEquals(7, context_inspection::test_context_cache_size()); // depends on number of default blocks
|
||||
|
||||
// ====== assign_capability(), unassign_capability() ====================
|
||||
|
||||
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
|
||||
$this->assertFalse($rc);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext->id);
|
||||
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
|
||||
$this->assertEquals($rc->permission, CAP_ALLOW);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext->id);
|
||||
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
|
||||
$this->assertEquals($rc->permission, CAP_ALLOW);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext, true);
|
||||
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
|
||||
$this->assertEquals($rc->permission, CAP_PREVENT);
|
||||
|
||||
assign_capability('moodle/site:accessallgroups', CAP_INHERIT, $allroles['teacher'], $frontpagecontext);
|
||||
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
|
||||
$this->assertFalse($rc);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext);
|
||||
unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext, true);
|
||||
$rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
|
||||
$this->assertFalse($rc);
|
||||
unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id, true);
|
||||
unset($rc);
|
||||
|
||||
accesslib_clear_all_caches(false); // must be done after assign_capability()
|
||||
|
||||
|
||||
// ======= role_assign(), role_unassign(), role_unassign_all() ==============
|
||||
|
||||
$context = context_course::instance($testcourses[1]);
|
||||
$this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0);
|
||||
role_assign($allroles['teacher'], $testusers[1], $context->id);
|
||||
role_assign($allroles['teacher'], $testusers[2], $context->id);
|
||||
role_assign($allroles['manager'], $testusers[1], $context->id);
|
||||
$this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 3);
|
||||
role_unassign($allroles['teacher'], $testusers[1], $context->id);
|
||||
$this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 2);
|
||||
role_unassign_all(array('contextid'=>$context->id));
|
||||
$this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0);
|
||||
unset($context);
|
||||
|
||||
accesslib_clear_all_caches(false); // just in case
|
||||
|
||||
|
||||
// ====== has_capability(), get_users_by_capability(), role_switch(), reload_all_capabilities() and friends ========================
|
||||
|
||||
$adminid = get_admin()->id;
|
||||
$guestid = $CFG->siteguest;
|
||||
|
||||
// Enrol some users into some courses
|
||||
$course1 = $DB->get_record('course', array('id'=>$testcourses[22]), '*', MUST_EXIST);
|
||||
$course2 = $DB->get_record('course', array('id'=>$testcourses[7]), '*', MUST_EXIST);
|
||||
$cms = $DB->get_records('course_modules', array('course'=>$course1->id), 'id');
|
||||
$cm1 = reset($cms);
|
||||
$blocks = $DB->get_records('block_instances', array('parentcontextid'=>context_module::instance($cm1->id)->id), 'id');
|
||||
$block1 = reset($blocks);
|
||||
$instance1 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course1->id));
|
||||
$instance2 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course2->id));
|
||||
for($i=0; $i<9; $i++) {
|
||||
$manualenrol->enrol_user($instance1, $testusers[$i], $allroles['student']);
|
||||
}
|
||||
$manualenrol->enrol_user($instance1, $testusers[8], $allroles['teacher']);
|
||||
$manualenrol->enrol_user($instance1, $testusers[9], $allroles['editingteacher']);
|
||||
|
||||
for($i=10; $i<15; $i++) {
|
||||
$manualenrol->enrol_user($instance2, $testusers[$i], $allroles['student']);
|
||||
}
|
||||
$manualenrol->enrol_user($instance2, $testusers[15], $allroles['editingteacher']);
|
||||
|
||||
// Add tons of role assignments - the more the better
|
||||
role_assign($allroles['coursecreator'], $testusers[11], context_coursecat::instance($testcategories[2]));
|
||||
role_assign($allroles['manager'], $testusers[12], context_coursecat::instance($testcategories[1]));
|
||||
role_assign($allroles['student'], $testusers[9], context_module::instance($cm1->id));
|
||||
role_assign($allroles['teacher'], $testusers[8], context_module::instance($cm1->id));
|
||||
role_assign($allroles['guest'], $testusers[13], context_course::instance($course1->id));
|
||||
role_assign($allroles['teacher'], $testusers[7], context_block::instance($block1->id));
|
||||
role_assign($allroles['manager'], $testusers[9], context_block::instance($block1->id));
|
||||
role_assign($allroles['editingteacher'], $testusers[9], context_course::instance($course1->id));
|
||||
|
||||
role_assign($allroles['teacher'], $adminid, context_course::instance($course1->id));
|
||||
role_assign($allroles['editingteacher'], $adminid, context_block::instance($block1->id));
|
||||
|
||||
// Add tons of overrides - the more the better
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpageblockcontext, true);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpageblockcontext, true);
|
||||
assign_capability('moodle/block:view', CAP_PROHIBIT, $allroles['guest'], $frontpageblockcontext, true);
|
||||
assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['user'], $frontpageblockcontext, true);
|
||||
assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['student'], $frontpageblockcontext, true);
|
||||
|
||||
assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $CFG->defaultuserroleid, $frontpagepagecontext, true);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagepagecontext, true);
|
||||
assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $frontpagepagecontext, true);
|
||||
assign_capability('mod/page:view', CAP_ALLOW, $allroles['user'], $frontpagepagecontext, true);
|
||||
assign_capability('moodle/page:view', CAP_ALLOW, $allroles['student'], $frontpagepagecontext, true);
|
||||
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpagecontext, true);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagecontext, true);
|
||||
assign_capability('mod/page:view', CAP_ALLOW, $allroles['guest'], $frontpagecontext, true);
|
||||
assign_capability('mod/page:view', CAP_PROHIBIT, $allroles['user'], $frontpagecontext, true);
|
||||
|
||||
assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $systemcontext, true);
|
||||
|
||||
accesslib_clear_all_caches(false); // must be done after assign_capability()
|
||||
|
||||
// Extra tests for guests and not-logged-in users because they can not be verified by cross checking
|
||||
// with get_users_by_capability() where they are ignored
|
||||
$this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, $guestid));
|
||||
$this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, $guestid));
|
||||
$this->assertTrue(has_capability('mod/page:view', $frontpagecontext, $guestid));
|
||||
$this->assertFalse(has_capability('mod/page:view', $systemcontext, $guestid));
|
||||
|
||||
$this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, 0));
|
||||
$this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, 0));
|
||||
$this->assertTrue(has_capability('mod/page:view', $frontpagecontext, 0));
|
||||
$this->assertFalse(has_capability('mod/page:view', $systemcontext, 0));
|
||||
|
||||
$this->assertFalse(has_capability('moodle/course:create', $systemcontext, $testusers[11]));
|
||||
$this->assertTrue(has_capability('moodle/course:create', context_coursecat::instance($testcategories[2]), $testusers[11]));
|
||||
$this->assertFalse(has_capability('moodle/course:create', context_course::instance($testcourses[1]), $testusers[11]));
|
||||
$this->assertTrue(has_capability('moodle/course:create', context_course::instance($testcourses[19]), $testusers[11]));
|
||||
|
||||
$this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[1]), $testusers[9]));
|
||||
$this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[19]), $testusers[9]));
|
||||
$this->assertFalse(has_capability('moodle/course:update', $systemcontext, $testusers[9]));
|
||||
|
||||
// Test the list of enrolled users
|
||||
$coursecontext = context_course::instance($course1->id);
|
||||
$enrolled = get_enrolled_users($coursecontext);
|
||||
$this->assertEquals(count($enrolled), 10);
|
||||
for($i=0; $i<10; $i++) {
|
||||
$this->assertTrue(isset($enrolled[$testusers[$i]]));
|
||||
}
|
||||
$enrolled = get_enrolled_users($coursecontext, 'moodle/course:update');
|
||||
$this->assertEquals(count($enrolled), 1);
|
||||
$this->assertTrue(isset($enrolled[$testusers[9]]));
|
||||
unset($enrolled);
|
||||
|
||||
// role switching
|
||||
$userid = $testusers[9];
|
||||
$USER = $DB->get_record('user', array('id'=>$userid));
|
||||
load_all_capabilities();
|
||||
$coursecontext = context_course::instance($course1->id);
|
||||
$this->assertTrue(has_capability('moodle/course:update', $coursecontext));
|
||||
$this->assertFalse(is_role_switched($course1->id));
|
||||
role_switch($allroles['student'], $coursecontext);
|
||||
$this->assertTrue(is_role_switched($course1->id));
|
||||
$this->assertEquals($USER->access['rsw'][$coursecontext->path], $allroles['student']);
|
||||
$this->assertFalse(has_capability('moodle/course:update', $coursecontext));
|
||||
reload_all_capabilities();
|
||||
$this->assertFalse(has_capability('moodle/course:update', $coursecontext));
|
||||
role_switch(0, $coursecontext);
|
||||
$this->assertTrue(has_capability('moodle/course:update', $coursecontext));
|
||||
$userid = $adminid;
|
||||
$USER = $DB->get_record('user', array('id'=>$userid));
|
||||
load_all_capabilities();
|
||||
$coursecontext = context_course::instance($course1->id);
|
||||
$blockcontext = context_block::instance($block1->id);
|
||||
$this->assertTrue(has_capability('moodle/course:update', $blockcontext));
|
||||
role_switch($allroles['student'], $coursecontext);
|
||||
$this->assertEquals($USER->access['rsw'][$coursecontext->path], $allroles['student']);
|
||||
$this->assertFalse(has_capability('moodle/course:update', $blockcontext));
|
||||
reload_all_capabilities();
|
||||
$this->assertFalse(has_capability('moodle/course:update', $blockcontext));
|
||||
load_all_capabilities();
|
||||
$this->assertTrue(has_capability('moodle/course:update', $blockcontext));
|
||||
|
||||
// temp course role for enrol
|
||||
$DB->delete_records('cache_flags', array()); // this prevents problem with dirty contexts immediately resetting the temp role - this is a known problem...
|
||||
$userid = $testusers[5];
|
||||
$roleid = $allroles['editingteacher'];
|
||||
$USER = $DB->get_record('user', array('id'=>$userid));
|
||||
load_all_capabilities();
|
||||
$coursecontext = context_course::instance($course1->id);
|
||||
$this->assertFalse(has_capability('moodle/course:update', $coursecontext));
|
||||
$this->assertFalse(isset($USER->access['ra'][$coursecontext->path][$roleid]));
|
||||
load_temp_course_role($coursecontext, $roleid);
|
||||
$this->assertEquals($USER->access['ra'][$coursecontext->path][$roleid], $roleid);
|
||||
$this->assertTrue(has_capability('moodle/course:update', $coursecontext));
|
||||
remove_temp_course_roles($coursecontext);
|
||||
$this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid));
|
||||
load_temp_course_role($coursecontext, $roleid);
|
||||
reload_all_capabilities();
|
||||
$this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid));
|
||||
$USER = new stdClass();
|
||||
$USER->id = 0;
|
||||
|
||||
// Now cross check has_capability() with get_users_by_capability(), each using different code paths,
|
||||
// they have to be kept in sync, usually only one of them breaks, so we know when something is wrong,
|
||||
// at the same time validate extra restrictions (guest read only no risks, admin exception, non existent and deleted users)
|
||||
$contexts = $DB->get_records('context', array(), 'id');
|
||||
$contexts = array_values($contexts);
|
||||
$capabilities = $DB->get_records('capabilities', array(), 'id');
|
||||
$capabilities = array_values($capabilities);
|
||||
$roles = array($allroles['guest'], $allroles['user'], $allroles['teacher'], $allroles['editingteacher'], $allroles['coursecreator'], $allroles['manager']);
|
||||
|
||||
if (PHPUNIT_LONGTEST) {
|
||||
// Random time!
|
||||
srand(666);
|
||||
foreach($testusers as $userid) { // no guest or deleted
|
||||
// each user gets 0-20 random roles
|
||||
$rcount = rand(0, 20);
|
||||
for($j=0; $j<$rcount; $j++) {
|
||||
$roleid = $roles[rand(0, count($roles)-1)];
|
||||
$contextid = $contexts[rand(0, count($contexts)-1)]->id;
|
||||
role_assign($roleid, $userid, $contextid);
|
||||
}
|
||||
}
|
||||
$permissions = array(CAP_ALLOW, CAP_PREVENT, CAP_INHERIT, CAP_PREVENT);
|
||||
for($j=0; $j<1000; $j++) {
|
||||
$roleid = $roles[rand(0, count($roles)-1)];
|
||||
$contextid = $contexts[rand(0, count($contexts)-1)]->id;
|
||||
$permission = $permissions[rand(0,count($permissions)-1)];
|
||||
$capname = $capabilities[rand(0, count($capabilities)-1)]->name;
|
||||
assign_capability($capname, $permission, $roleid, $contextid, true);
|
||||
}
|
||||
unset($permissions);
|
||||
unset($roles);
|
||||
unset($contexts);
|
||||
unset($users);
|
||||
unset($capabilities);
|
||||
|
||||
accesslib_clear_all_caches(false); // must be done after assign_capability()
|
||||
|
||||
// Test time - let's set up some real user, just in case the logic for USER affects the others...
|
||||
$USER = $DB->get_record('user', array('id'=>$testusers[3]));
|
||||
load_all_capabilities();
|
||||
|
||||
$contexts = $DB->get_records('context', array(), 'id');
|
||||
$users = $DB->get_records('user', array(), 'id', 'id');
|
||||
$capabilities = $DB->get_records('capabilities', array(), 'id');
|
||||
$users[0] = null; // not-logged-in user
|
||||
$users[-1] = null; // non-existent user
|
||||
|
||||
} else {
|
||||
// context testing takes a very long time...
|
||||
$contexts = array();
|
||||
}
|
||||
|
||||
foreach ($contexts as $crecord) {
|
||||
$context = context::instance_by_id($crecord->id);
|
||||
if ($coursecontext = $context->get_course_context(false)) {
|
||||
$enrolled = get_enrolled_users($context);
|
||||
} else {
|
||||
$enrolled = array();
|
||||
}
|
||||
foreach ($capabilities as $cap) {
|
||||
$allowed = get_users_by_capability($context, $cap->name, 'u.id, u.username');
|
||||
if ($enrolled) {
|
||||
$enrolledwithcap = get_enrolled_users($context, $cap->name);
|
||||
} else {
|
||||
$enrolledwithcap = array();
|
||||
}
|
||||
foreach ($users as $userid=>$unused) {
|
||||
if ($userid == 0 or isguestuser($userid)) {
|
||||
if ($userid == 0) {
|
||||
$CFG->forcelogin = true;
|
||||
$this->assertFalse(has_capability($cap->name, $context, $userid));
|
||||
unset($CFG->forcelogin);
|
||||
}
|
||||
if (($cap->captype === 'write') or ($cap->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))) {
|
||||
$this->assertFalse(has_capability($cap->name, $context, $userid));
|
||||
}
|
||||
$this->assertFalse(isset($allowed[$userid]));
|
||||
} else {
|
||||
if (is_siteadmin($userid)) {
|
||||
$this->assertTrue(has_capability($cap->name, $context, $userid, true));
|
||||
}
|
||||
$hascap = has_capability($cap->name, $context, $userid, false);
|
||||
$this->assertSame($hascap, isset($allowed[$userid]), "Capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." ");
|
||||
if (isset($enrolled[$userid])) {
|
||||
$this->assertSame(isset($allowed[$userid]), isset($enrolledwithcap[$userid]), "Enrolment with capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Back to nobody
|
||||
$USER = new stdClass();
|
||||
$USER->id = 0;
|
||||
unset($contexts);
|
||||
unset($users);
|
||||
unset($capabilities);
|
||||
|
||||
// Now let's do all the remaining tests that break our carefully prepared fake site
|
||||
|
||||
|
||||
|
||||
// ======= $context->mark_dirty() =======================================
|
||||
|
||||
$DB->delete_records('cache_flags', array());
|
||||
accesslib_clear_all_caches(false);
|
||||
$systemcontext->mark_dirty();
|
||||
$dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
|
||||
$this->assertTrue(isset($dirty[$systemcontext->path]));
|
||||
$this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$systemcontext->path]));
|
||||
|
||||
|
||||
// ======= $context->reload_if_dirty(); =================================
|
||||
|
||||
$DB->delete_records('cache_flags', array());
|
||||
accesslib_clear_all_caches(false);
|
||||
load_all_capabilities();
|
||||
$context = context_course::instance($testcourses[2]);
|
||||
$page = $DB->get_record('page', array('course'=>$testcourses[2]));
|
||||
$pagecontext = context_module::instance($page->id);
|
||||
|
||||
$context->mark_dirty();
|
||||
$this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path]));
|
||||
$USER->access['test'] = true;
|
||||
$context->reload_if_dirty();
|
||||
$this->assertFalse(isset($USER->access['test']));
|
||||
|
||||
$context->mark_dirty();
|
||||
$this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path]));
|
||||
$USER->access['test'] = true;
|
||||
$pagecontext->reload_if_dirty();
|
||||
$this->assertFalse(isset($USER->access['test']));
|
||||
|
||||
|
||||
// ======= context_helper::build_all_paths() ============================
|
||||
|
||||
$oldcontexts = $DB->get_records('context', array(), 'id');
|
||||
$DB->set_field_select('context', 'path', NULL, "contextlevel <> ".CONTEXT_SYSTEM);
|
||||
$DB->set_field_select('context', 'depth', 0, "contextlevel <> ".CONTEXT_SYSTEM);
|
||||
context_helper::build_all_paths();
|
||||
$newcontexts = $DB->get_records('context', array(), 'id');
|
||||
$this->assertEquals($oldcontexts, $newcontexts);
|
||||
unset($oldcontexts);
|
||||
unset($newcontexts);
|
||||
|
||||
|
||||
// ======= $context->reset_paths() ======================================
|
||||
|
||||
$context = context_course::instance($testcourses[2]);
|
||||
$children = $context->get_child_contexts();
|
||||
$context->reset_paths(false);
|
||||
$this->assertSame($DB->get_field('context', 'path', array('id'=>$context->id)), NULL);
|
||||
$this->assertEquals($DB->get_field('context', 'depth', array('id'=>$context->id)), 0);
|
||||
foreach ($children as $child) {
|
||||
$this->assertSame($DB->get_field('context', 'path', array('id'=>$child->id)), NULL);
|
||||
$this->assertEquals($DB->get_field('context', 'depth', array('id'=>$child->id)), 0);
|
||||
}
|
||||
$this->assertEquals(count($children)+1, $DB->count_records('context', array('depth'=>0)));
|
||||
$this->assertEquals(count($children)+1, $DB->count_records('context', array('path'=>NULL)));
|
||||
|
||||
$context = context_course::instance($testcourses[2]);
|
||||
$context->reset_paths(true);
|
||||
$context = context_course::instance($testcourses[2]);
|
||||
$this->assertEquals($DB->get_field('context', 'path', array('id'=>$context->id)), $context->path);
|
||||
$this->assertEquals($DB->get_field('context', 'depth', array('id'=>$context->id)), $context->depth);
|
||||
$this->assertEquals(0, $DB->count_records('context', array('depth'=>0)));
|
||||
$this->assertEquals(0, $DB->count_records('context', array('path'=>NULL)));
|
||||
|
||||
|
||||
// ====== $context->update_moved(); ======================================
|
||||
|
||||
accesslib_clear_all_caches(false);
|
||||
$DB->delete_records('cache_flags', array());
|
||||
$course = $DB->get_record('course', array('id'=>$testcourses[0]));
|
||||
$context = context_course::instance($course->id);
|
||||
$oldpath = $context->path;
|
||||
$miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}");
|
||||
$categorycontext = context_coursecat::instance($miscid);
|
||||
$course->category = $miscid;
|
||||
$DB->update_record('course', $course);
|
||||
$context->update_moved($categorycontext);
|
||||
|
||||
$context = context_course::instance($course->id);
|
||||
$this->assertEquals($context->get_parent_context(), $categorycontext);
|
||||
$dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
|
||||
$this->assertTrue(isset($dirty[$oldpath]));
|
||||
$this->assertTrue(isset($dirty[$context->path]));
|
||||
|
||||
|
||||
// ====== $context->delete_content() =====================================
|
||||
|
||||
context_helper::reset_caches();
|
||||
$context = context_module::instance($testpages[3]);
|
||||
$this->assertTrue($DB->record_exists('context', array('id'=>$context->id)));
|
||||
$this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));
|
||||
$context->delete_content();
|
||||
$this->assertTrue($DB->record_exists('context', array('id'=>$context->id)));
|
||||
$this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));
|
||||
|
||||
|
||||
// ====== $context->delete() =============================
|
||||
|
||||
context_helper::reset_caches();
|
||||
$context = context_module::instance($testpages[4]);
|
||||
$this->assertTrue($DB->record_exists('context', array('id'=>$context->id)));
|
||||
$this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));
|
||||
$bi = $DB->get_record('block_instances', array('parentcontextid'=>$context->id));
|
||||
$bicontext = context_block::instance($bi->id);
|
||||
$DB->delete_records('cache_flags', array());
|
||||
$context->delete(); // should delete also linked blocks
|
||||
$dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
|
||||
$this->assertTrue(isset($dirty[$context->path]));
|
||||
$this->assertFalse($DB->record_exists('context', array('id'=>$context->id)));
|
||||
$this->assertFalse($DB->record_exists('context', array('id'=>$bicontext->id)));
|
||||
$this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_MODULE, 'instanceid'=>$testpages[4])));
|
||||
$this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK, 'instanceid'=>$bi->id)));
|
||||
$this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));
|
||||
context_module::instance($testpages[4]);
|
||||
|
||||
|
||||
// ====== context_helper::delete_instance() =============================
|
||||
|
||||
context_helper::reset_caches();
|
||||
$lastcourse = array_pop($testcourses);
|
||||
$this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse)));
|
||||
$coursecontext = context_course::instance($lastcourse);
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), 1);
|
||||
$this->assertFalse($coursecontext->instanceid == CONTEXT_COURSE);
|
||||
$DB->delete_records('cache_flags', array());
|
||||
context_helper::delete_instance(CONTEXT_COURSE, $lastcourse);
|
||||
$dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
|
||||
$this->assertTrue(isset($dirty[$coursecontext->path]));
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), 0);
|
||||
$this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse)));
|
||||
context_course::instance($lastcourse);
|
||||
|
||||
|
||||
// ======= context_helper::create_instances() ==========================
|
||||
|
||||
$prevcount = $DB->count_records('context');
|
||||
$DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK));
|
||||
context_helper::create_instances(null, true);
|
||||
$this->assertSame($DB->count_records('context'), $prevcount);
|
||||
$this->assertEquals($DB->count_records('context', array('depth'=>0)), 0);
|
||||
$this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0);
|
||||
|
||||
$DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK));
|
||||
$DB->delete_records('block_instances', array());
|
||||
$prevcount = $DB->count_records('context');
|
||||
$DB->delete_records_select('context', 'contextlevel <> '.CONTEXT_SYSTEM);
|
||||
context_helper::create_instances(null, true);
|
||||
$this->assertSame($DB->count_records('context'), $prevcount);
|
||||
$this->assertEquals($DB->count_records('context', array('depth'=>0)), 0);
|
||||
$this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0);
|
||||
|
||||
|
||||
// ======= context_helper::cleanup_instances() ==========================
|
||||
|
||||
$lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}");
|
||||
$DB->delete_records('course', array('id'=>$lastcourse));
|
||||
$lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}");
|
||||
$DB->delete_records('course_categories', array('id'=>$lastcategory));
|
||||
$lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0");
|
||||
$DB->delete_records('user', array('id'=>$lastuser));
|
||||
$DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id));
|
||||
$DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid));
|
||||
context_helper::cleanup_instances();
|
||||
$count = 1; //system
|
||||
$count += $DB->count_records('user', array('deleted'=>0));
|
||||
$count += $DB->count_records('course_categories');
|
||||
$count += $DB->count_records('course');
|
||||
$count += $DB->count_records('course_modules');
|
||||
$count += $DB->count_records('block_instances');
|
||||
$this->assertEquals($DB->count_records('context'), $count);
|
||||
|
||||
|
||||
// ======= context cache size restrictions ==============================
|
||||
|
||||
$testusers= array();
|
||||
for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) {
|
||||
$user = $generator->create_user();
|
||||
$testusers[$i] = $user->id;
|
||||
}
|
||||
context_helper::create_instances(null, true);
|
||||
context_helper::reset_caches();
|
||||
for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) {
|
||||
context_user::instance($testusers[$i]);
|
||||
if ($i == CONTEXT_CACHE_MAX_SIZE - 1) {
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), CONTEXT_CACHE_MAX_SIZE);
|
||||
} else if ($i == CONTEXT_CACHE_MAX_SIZE) {
|
||||
// once the limit is reached roughly 1/3 of records should be removed from cache
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), (int)(CONTEXT_CACHE_MAX_SIZE * (2/3) +102));
|
||||
}
|
||||
}
|
||||
// We keep the first 100 cached
|
||||
$prevsize = context_inspection::test_context_cache_size();
|
||||
for ($i=0; $i<100; $i++) {
|
||||
context_user::instance($testusers[$i]);
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), $prevsize);
|
||||
}
|
||||
context_user::instance($testusers[102]);
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), $prevsize+1);
|
||||
unset($testusers);
|
||||
|
||||
|
||||
|
||||
// =================================================================
|
||||
// ======= basic test of legacy functions ==========================
|
||||
// =================================================================
|
||||
// note: watch out, the fake site might be pretty borked already
|
||||
|
||||
$this->assertSame(get_system_context(), context_system::instance());
|
||||
|
||||
foreach ($DB->get_records('context') as $contextid=>$record) {
|
||||
$context = context::instance_by_id($contextid);
|
||||
$this->assertSame(get_context_instance_by_id($contextid), $context);
|
||||
$this->assertSame(get_context_instance($record->contextlevel, $record->instanceid), $context);
|
||||
$this->assertSame(get_parent_contexts($context), $context->get_parent_context_ids());
|
||||
if ($context->id == SYSCONTEXTID) {
|
||||
$this->assertSame(get_parent_contextid($context), false);
|
||||
} else {
|
||||
$this->assertSame(get_parent_contextid($context), $context->get_parent_context()->id);
|
||||
}
|
||||
}
|
||||
|
||||
$CFG->debug = 0;
|
||||
$children = get_child_contexts($systemcontext);
|
||||
$CFG->debug = DEBUG_DEVELOPER;
|
||||
$this->assertEquals(count($children), $DB->count_records('context')-1);
|
||||
unset($children);
|
||||
|
||||
$DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK));
|
||||
create_contexts();
|
||||
$this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK)));
|
||||
|
||||
$DB->set_field('context', 'depth', 0, array('contextlevel'=>CONTEXT_BLOCK));
|
||||
build_context_path();
|
||||
$this->assertFalse($DB->record_exists('context', array('depth'=>0)));
|
||||
|
||||
$lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}");
|
||||
$DB->delete_records('course', array('id'=>$lastcourse));
|
||||
$lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}");
|
||||
$DB->delete_records('course_categories', array('id'=>$lastcategory));
|
||||
$lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0");
|
||||
$DB->delete_records('user', array('id'=>$lastuser));
|
||||
$DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id));
|
||||
$DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid));
|
||||
cleanup_contexts();
|
||||
$count = 1; //system
|
||||
$count += $DB->count_records('user', array('deleted'=>0));
|
||||
$count += $DB->count_records('course_categories');
|
||||
$count += $DB->count_records('course');
|
||||
$count += $DB->count_records('course_modules');
|
||||
$count += $DB->count_records('block_instances');
|
||||
$this->assertEquals($DB->count_records('context'), $count);
|
||||
|
||||
context_helper::reset_caches();
|
||||
preload_course_contexts($SITE->id);
|
||||
$this->assertEquals(context_inspection::test_context_cache_size(), 1);
|
||||
|
||||
context_helper::reset_caches();
|
||||
list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSECAT, 'ctx');
|
||||
$sql = "SELECT c.id $select FROM {course_categories} c $join";
|
||||
$records = $DB->get_records_sql($sql);
|
||||
foreach ($records as $record) {
|
||||
context_instance_preload($record);
|
||||
$record = (array)$record;
|
||||
$this->assertEquals(1, count($record)); // only id left
|
||||
}
|
||||
$this->assertEquals(count($records), context_inspection::test_context_cache_size());
|
||||
|
||||
accesslib_clear_all_caches(true);
|
||||
$DB->delete_records('cache_flags', array());
|
||||
mark_context_dirty($systemcontext->path);
|
||||
$dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
|
||||
$this->assertTrue(isset($dirty[$systemcontext->path]));
|
||||
|
||||
accesslib_clear_all_caches(false);
|
||||
$DB->delete_records('cache_flags', array());
|
||||
$course = $DB->get_record('course', array('id'=>$testcourses[2]));
|
||||
$context = get_context_instance(CONTEXT_COURSE, $course->id);
|
||||
$oldpath = $context->path;
|
||||
$miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}");
|
||||
$categorycontext = context_coursecat::instance($miscid);
|
||||
$course->category = $miscid;
|
||||
$DB->update_record('course', $course);
|
||||
context_moved($context, $categorycontext);
|
||||
$context = get_context_instance(CONTEXT_COURSE, $course->id);
|
||||
$this->assertEquals($context->get_parent_context(), $categorycontext);
|
||||
|
||||
$this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2])));
|
||||
delete_context(CONTEXT_COURSE, $testcourses[2]);
|
||||
$this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2])));
|
||||
|
||||
$name = get_contextlevel_name(CONTEXT_COURSE);
|
||||
$this->assertFalse(empty($name));
|
||||
|
||||
$context = get_context_instance(CONTEXT_COURSE, $testcourses[2]);
|
||||
$name = print_context_name($context);
|
||||
$this->assertFalse(empty($name));
|
||||
|
||||
$url = get_context_url($coursecontext);
|
||||
$this->assertFalse($url instanceof modole_url);
|
||||
|
||||
$page = $DB->get_record('page', array('id'=>$testpages[7]));
|
||||
$context = get_context_instance(CONTEXT_MODULE, $page->id);
|
||||
$coursecontext = get_course_context($context);
|
||||
$this->assertEquals($coursecontext->contextlevel, CONTEXT_COURSE);
|
||||
$this->assertEquals(get_courseid_from_context($context), $page->course);
|
||||
|
||||
$caps = fetch_context_capabilities($systemcontext);
|
||||
$this->assertTrue(is_array($caps));
|
||||
unset($caps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,386 @@
|
||||
<?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 the block_manager class in ../blocklib.php.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/pagelib.php');
|
||||
require_once($CFG->libdir . '/blocklib.php');
|
||||
require_once($CFG->dirroot . '/blocks/moodleblock.class.php');
|
||||
|
||||
|
||||
/** Test-specific subclass to make some protected things public. */
|
||||
class testable_block_manager extends block_manager {
|
||||
|
||||
public function mark_loaded() {
|
||||
$this->birecordsbyregion = array();
|
||||
}
|
||||
public function get_loaded_blocks() {
|
||||
return $this->birecordsbyregion;
|
||||
}
|
||||
}
|
||||
class block_ablocktype extends block_base {
|
||||
public function init() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test functions that don't need to touch the database.
|
||||
*/
|
||||
class moodle_block_manager_testcase extends basic_testcase {
|
||||
protected $testpage;
|
||||
protected $blockmanager;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->testpage = new moodle_page();
|
||||
$this->testpage->set_context(get_context_instance(CONTEXT_SYSTEM));
|
||||
$this->blockmanager = new testable_block_manager($this->testpage);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
$this->testpage = null;
|
||||
$this->blockmanager = null;
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function test_no_regions_initially() {
|
||||
// Exercise SUT & Validate
|
||||
$this->assertEquals(array(), $this->blockmanager->get_regions());
|
||||
}
|
||||
|
||||
public function test_add_region() {
|
||||
// Exercise SUT.
|
||||
$this->blockmanager->add_region('a-region-name');
|
||||
// Validate
|
||||
$this->assertEquals(array('a-region-name'), $this->blockmanager->get_regions());
|
||||
}
|
||||
|
||||
public function test_add_regions() {
|
||||
// Set up fixture.
|
||||
$regions = array('a-region', 'another-region');
|
||||
// Exercise SUT.
|
||||
$this->blockmanager->add_regions($regions);
|
||||
// Validate
|
||||
$this->assertEquals($regions, $this->blockmanager->get_regions(), '', 0, 10, true);
|
||||
}
|
||||
|
||||
public function test_add_region_twice() {
|
||||
// Exercise SUT.
|
||||
$this->blockmanager->add_region('a-region-name');
|
||||
$this->blockmanager->add_region('another-region');
|
||||
// Validate
|
||||
$this->assertEquals(array('a-region-name', 'another-region'), $this->blockmanager->get_regions(), '', 0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_cannot_add_region_after_loaded() {
|
||||
// Set up fixture.
|
||||
$this->blockmanager->mark_loaded();
|
||||
// Exercise SUT.
|
||||
$this->blockmanager->add_region('too-late');
|
||||
}
|
||||
|
||||
public function test_set_default_region() {
|
||||
// Set up fixture.
|
||||
$this->blockmanager->add_region('a-region-name');
|
||||
// Exercise SUT.
|
||||
$this->blockmanager->set_default_region('a-region-name');
|
||||
// Validate
|
||||
$this->assertEquals('a-region-name', $this->blockmanager->get_default_region());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_cannot_set_unknown_region_as_default() {
|
||||
// Exercise SUT.
|
||||
$this->blockmanager->set_default_region('a-region-name');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_cannot_change_default_region_after_loaded() {
|
||||
// Set up fixture.
|
||||
$this->blockmanager->mark_loaded();
|
||||
// Exercise SUT.
|
||||
$this->blockmanager->set_default_region('too-late');
|
||||
}
|
||||
|
||||
public function test_matching_page_type_patterns() {
|
||||
$this->assertEquals(array('site-index', 'site-index-*', 'site-*', '*'),
|
||||
matching_page_type_patterns('site-index'), '', 0, 10, true);
|
||||
|
||||
$this->assertEquals(array('mod-quiz-report-overview', 'mod-quiz-report-overview-*', 'mod-quiz-report-*', 'mod-quiz-*', 'mod-*', '*'),
|
||||
matching_page_type_patterns('mod-quiz-report-overview'), '', 0, 10, true);
|
||||
|
||||
$this->assertEquals(array('mod-forum-view', 'mod-*-view', 'mod-forum-view-*', 'mod-forum-*', 'mod-*', '*'),
|
||||
matching_page_type_patterns('mod-forum-view'), '', 0, 10, true);
|
||||
|
||||
$this->assertEquals(array('mod-forum-index', 'mod-*-index', 'mod-forum-index-*', 'mod-forum-*', 'mod-*', '*'),
|
||||
matching_page_type_patterns('mod-forum-index'), '', 0, 10, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test methods that load and save data from block_instances and block_positions.
|
||||
*/
|
||||
class moodle_block_manager_test_saving_loading_testcase extends advanced_testcase {
|
||||
|
||||
protected $isediting = null;
|
||||
|
||||
protected function purge_blocks() {
|
||||
global $DB;
|
||||
$bis = $DB->get_records('block_instances');
|
||||
foreach($bis as $instance) {
|
||||
blocks_delete_instance($instance);
|
||||
}
|
||||
$this->resetAfterTest(true);
|
||||
}
|
||||
|
||||
protected function get_a_page_and_block_manager($regions, $context, $pagetype, $subpage = '') {
|
||||
$page = new moodle_page;
|
||||
$page->set_context($context);
|
||||
$page->set_pagetype($pagetype);
|
||||
$page->set_subpage($subpage);
|
||||
|
||||
$blockmanager = new testable_block_manager($page);
|
||||
$blockmanager->add_regions($regions);
|
||||
$blockmanager->set_default_region($regions[0]);
|
||||
|
||||
return array($page, $blockmanager);
|
||||
}
|
||||
|
||||
protected function get_a_known_block_type() {
|
||||
global $DB;
|
||||
$block = new stdClass;
|
||||
$block->name = 'ablocktype';
|
||||
$DB->insert_record('block', $block);
|
||||
return $block->name;
|
||||
}
|
||||
|
||||
protected function assertContainsBlocksOfType($typearray, $blockarray) {
|
||||
if (!$this->assertEquals(count($typearray), count($blockarray), "Blocks array contains the wrong number of elements %s.")) {
|
||||
return;
|
||||
}
|
||||
$types = array_values($typearray);
|
||||
$i = 0;
|
||||
foreach ($blockarray as $block) {
|
||||
$blocktype = $types[$i];
|
||||
$this->assertEquals($blocktype, $block->name(), "Block types do not match at postition $i %s.");
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
public function test_empty_initially() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
|
||||
get_context_instance(CONTEXT_SYSTEM), 'page-type');
|
||||
// Exercise SUT.
|
||||
$blockmanager->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $blockmanager->get_loaded_blocks();
|
||||
$this->assertEquals(array('a-region' => array()), $blocks);
|
||||
}
|
||||
|
||||
public function test_adding_and_retrieving_one_block() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
$context = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
|
||||
$context, 'page-type');
|
||||
|
||||
// Exercise SUT.
|
||||
$blockmanager->add_block($blockname, $regionname, 0, false);
|
||||
$blockmanager->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array($blockname), $blocks);
|
||||
}
|
||||
|
||||
public function test_adding_and_retrieving_two_blocks() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
$context = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
|
||||
$context, 'page-type');
|
||||
|
||||
// Exercise SUT.
|
||||
$blockmanager->add_block($blockname, $regionname, 0, false);
|
||||
$blockmanager->add_block($blockname, $regionname, 1, false);
|
||||
$blockmanager->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array($blockname, $blockname), $blocks);
|
||||
}
|
||||
|
||||
public function test_block_not_included_in_different_context() {
|
||||
global $DB;
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$syscontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
$cat = new stdClass();
|
||||
$cat->name = 'testcategory';
|
||||
$cat->parent = 0;
|
||||
$cat->depth = 1;
|
||||
$cat->sortorder = 100;
|
||||
$cat->timemodified = time();
|
||||
$catid = $DB->insert_record('course_categories', $cat);
|
||||
$DB->set_field('course_categories', 'path', '/' . $catid, array('id' => $catid));
|
||||
$fakecontext = context_coursecat::instance($catid);
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
|
||||
list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $fakecontext, 'page-type');
|
||||
list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
|
||||
|
||||
$addbm->add_block($blockname, $regionname, 0, false);
|
||||
|
||||
// Exercise SUT.
|
||||
$viewbm->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $viewbm->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array(), $blocks);
|
||||
}
|
||||
|
||||
public function test_block_included_in_sub_context() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$syscontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
$childcontext = context_coursecat::instance(1);
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
|
||||
list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
|
||||
list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $childcontext, 'page-type');
|
||||
|
||||
$addbm->add_block($blockname, $regionname, 0, true);
|
||||
|
||||
// Exercise SUT.
|
||||
$viewbm->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $viewbm->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array($blockname), $blocks);
|
||||
}
|
||||
|
||||
public function test_block_not_included_on_different_page_type() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$syscontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
|
||||
list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
|
||||
list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'other-page-type');
|
||||
|
||||
$addbm->add_block($blockname, $regionname, 0, true);
|
||||
|
||||
// Exercise SUT.
|
||||
$viewbm->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $viewbm->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array(), $blocks);
|
||||
}
|
||||
|
||||
public function test_block_not_included_on_different_sub_page() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
$syscontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
|
||||
$syscontext, 'page-type', 'sub-page');
|
||||
|
||||
$blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, 'other-sub-page');
|
||||
|
||||
// Exercise SUT.
|
||||
$blockmanager->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array(), $blocks);
|
||||
}
|
||||
|
||||
public function test_block_included_with_explicit_sub_page() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
$syscontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
|
||||
$syscontext, 'page-type', 'sub-page');
|
||||
|
||||
$blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, $page->subpage);
|
||||
|
||||
// Exercise SUT.
|
||||
$blockmanager->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array($blockname), $blocks);
|
||||
}
|
||||
|
||||
public function test_block_included_with_page_type_pattern() {
|
||||
$this->purge_blocks();
|
||||
|
||||
// Set up fixture.
|
||||
$regionname = 'a-region';
|
||||
$blockname = $this->get_a_known_block_type();
|
||||
$syscontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
|
||||
$syscontext, 'page-type', 'sub-page');
|
||||
|
||||
$blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage);
|
||||
|
||||
// Exercise SUT.
|
||||
$blockmanager->load_blocks();
|
||||
// Validate.
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
$this->assertContainsBlocksOfType(array($blockname), $blocks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Code quality unit tests that are fast enough to run each time.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright © 2006 The Open University
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
class code_testcase extends advanced_testcase {
|
||||
protected $badstrings;
|
||||
protected $extensions_to_ignore = array('exe', 'gif', 'ico', 'jpg', 'png', 'ttf', 'log');
|
||||
protected $ignore_folders = array();
|
||||
|
||||
public function test_dnc() {
|
||||
global $CFG;
|
||||
$regexp = '/\.(' . implode('|', $this->extensions_to_ignore) . ')$/';
|
||||
$this->badstrings = array();
|
||||
$this->badstrings['DONOT' . 'COMMIT'] = 'DONOT' . 'COMMIT'; // If we put the literal string here, it fails the test!
|
||||
$this->badstrings['trailing whitespace'] = "[\t ][\r\n]";
|
||||
foreach ($this->badstrings as $description => $ignored) {
|
||||
$this->allok[$description] = true;
|
||||
}
|
||||
$this->recurseFolders($CFG->dirroot, 'search_file_for_dnc', $regexp, true);
|
||||
$this->assertTrue(true); // executed only if no file failed the test
|
||||
}
|
||||
|
||||
protected function search_file_for_dnc($filepath) {
|
||||
$content = file_get_contents($filepath);
|
||||
foreach ($this->badstrings as $description => $badstring) {
|
||||
if (stripos($content, $badstring) !== false) {
|
||||
$this->fail("File $filepath contains $description.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for /lib/componentlib.class.php.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2011 Tomasz Muras
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir.'/componentlib.class.php');
|
||||
|
||||
class componentlib_test extends advanced_testcase {
|
||||
|
||||
public function test_component_installer() {
|
||||
global $CFG;
|
||||
|
||||
$ci = new component_installer('http://download.moodle.org', 'unittest', 'downloadtests.zip');
|
||||
$this->assertTrue($ci->check_requisites());
|
||||
|
||||
$destpath = $CFG->dataroot.'/downloadtests';
|
||||
|
||||
//carefully remove component files to enforce fresh installation
|
||||
@unlink($destpath.'/'.'downloadtests.md5');
|
||||
@unlink($destpath.'/'.'test.html');
|
||||
@unlink($destpath.'/'.'test.jpg');
|
||||
@rmdir($destpath);
|
||||
|
||||
$this->assertEquals(COMPONENT_NEEDUPDATE, $ci->need_upgrade());
|
||||
|
||||
$status = $ci->install();
|
||||
$this->assertEquals(COMPONENT_INSTALLED, $status);
|
||||
$this->assertEquals('9e94f74b3efb1ff6cf075dc6b2abf15c', $ci->get_component_md5());
|
||||
|
||||
//it's already installed, so Moodle should detect it's up to date
|
||||
$this->assertEquals(COMPONENT_UPTODATE, $ci->need_upgrade());
|
||||
$status = $ci->install();
|
||||
$this->assertEquals(COMPONENT_UPTODATE, $status);
|
||||
|
||||
//check if correct files were downloaded
|
||||
$this->assertEquals('2af180e813dc3f446a9bb7b6af87ce24', md5_file($destpath.'/'.'test.jpg'));
|
||||
$this->assertEquals('47250a973d1b88d9445f94db4ef2c97a', md5_file($destpath.'/'.'test.html'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the public API of the {@link lang_installer} class
|
||||
*/
|
||||
public function test_lang_installer() {
|
||||
|
||||
// test the manipulation with the download queue
|
||||
$installer = new testable_lang_installer();
|
||||
$this->assertFalse($installer->protected_is_queued());
|
||||
$installer->protected_add_to_queue('cs');
|
||||
$installer->protected_add_to_queue(array('cs', 'sk'));
|
||||
$this->assertTrue($installer->protected_is_queued());
|
||||
$this->assertTrue($installer->protected_is_queued('cs'));
|
||||
$this->assertTrue($installer->protected_is_queued('sk'));
|
||||
$this->assertFalse($installer->protected_is_queued('de_kids'));
|
||||
$installer->set_queue('de_kids');
|
||||
$this->assertFalse($installer->protected_is_queued('cs'));
|
||||
$this->assertFalse($installer->protected_is_queued('sk'));
|
||||
$this->assertFalse($installer->protected_is_queued('de'));
|
||||
$this->assertFalse($installer->protected_is_queued('de_du'));
|
||||
$this->assertTrue($installer->protected_is_queued('de_kids'));
|
||||
$installer->set_queue(array('cs', 'de_kids'));
|
||||
$this->assertTrue($installer->protected_is_queued('cs'));
|
||||
$this->assertFalse($installer->protected_is_queued('sk'));
|
||||
$this->assertFalse($installer->protected_is_queued('de'));
|
||||
$this->assertFalse($installer->protected_is_queued('de_du'));
|
||||
$this->assertTrue($installer->protected_is_queued('de_kids'));
|
||||
$installer->set_queue(array());
|
||||
$this->assertFalse($installer->protected_is_queued());
|
||||
unset($installer);
|
||||
|
||||
// install a set of lang packs
|
||||
$installer = new testable_lang_installer(array('cs', 'de_kids', 'xx'));
|
||||
$result = $installer->run();
|
||||
$this->assertEquals($result['cs'], lang_installer::RESULT_UPTODATE);
|
||||
$this->assertEquals($result['de_kids'], lang_installer::RESULT_INSTALLED);
|
||||
$this->assertEquals($result['xx'], lang_installer::RESULT_DOWNLOADERROR);
|
||||
// the following two were automatically added to the queue
|
||||
$this->assertEquals($result['de_du'], lang_installer::RESULT_INSTALLED);
|
||||
$this->assertEquals($result['de'], lang_installer::RESULT_UPTODATE);
|
||||
|
||||
// exception throwing
|
||||
$installer = new testable_lang_installer(array('yy'));
|
||||
try {
|
||||
$installer->run();
|
||||
$this->fail('lang_installer_exception exception expected');
|
||||
} catch (Exception $e) {
|
||||
$this->assertEquals('lang_installer_exception', get_class($e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Testable lang_installer subclass that does not actually install anything
|
||||
* and provides access to the protected methods of the parent class
|
||||
*
|
||||
* @copyright 2011 David Mudrak <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class testable_lang_installer extends lang_installer {
|
||||
|
||||
/**
|
||||
* @see parent::is_queued()
|
||||
*/
|
||||
public function protected_is_queued($langcode = '') {
|
||||
return $this->is_queued($langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see parent::add_to_queue()
|
||||
*/
|
||||
public function protected_add_to_queue($langcodes) {
|
||||
return $this->add_to_queue($langcodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate lang pack installation via component_installer
|
||||
*
|
||||
* Language packages 'de_du' and 'de_kids' reported as installed
|
||||
* Language packages 'cs' and 'de' reported as up-to-date
|
||||
* Language package 'xx' returns download error
|
||||
* All other language packages will throw an unknown exception
|
||||
*
|
||||
* @see parent::install_language_pack()
|
||||
*/
|
||||
protected function install_language_pack($langcode) {
|
||||
|
||||
switch ($langcode) {
|
||||
case 'de_du':
|
||||
case 'de_kids':
|
||||
return self::RESULT_INSTALLED;
|
||||
|
||||
case 'cs':
|
||||
case 'de':
|
||||
return self::RESULT_UPTODATE;
|
||||
|
||||
case 'xx':
|
||||
return self::RESULT_DOWNLOADERROR;
|
||||
|
||||
default:
|
||||
throw new lang_installer_exception('testing-unknown-exception', $langcode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate detection of parent languge
|
||||
*
|
||||
* @see parent::get_parent_language()
|
||||
*/
|
||||
protected function get_parent_language($langcode) {
|
||||
|
||||
switch ($langcode) {
|
||||
case 'de_kids':
|
||||
return 'de_du';
|
||||
case 'de_du':
|
||||
return 'de';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,708 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* This file contains the unittests for the css optimiser in csslib.php
|
||||
*
|
||||
* @package core_css
|
||||
* @category phpunit
|
||||
* @copyright 2012 Sam Hemelryk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/csslib.php');
|
||||
|
||||
|
||||
/**
|
||||
* CSS optimiser test class
|
||||
*
|
||||
* @package core_css
|
||||
* @category css
|
||||
* @copyright 2012 Sam Hemelryk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class css_optimiser_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Sets up the test class
|
||||
*/
|
||||
public function setUp() {
|
||||
global $CFG;
|
||||
parent::setUp();
|
||||
// We need to disable these if they are enabled to that we can predict
|
||||
// the output.
|
||||
$CFG->cssoptimiserstats = false;
|
||||
$CFG->cssoptimiserpretty = false;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the process method
|
||||
*/
|
||||
public function test_process() {
|
||||
$optimiser = new css_optimiser;
|
||||
|
||||
$this->check_background($optimiser);
|
||||
$this->check_borders($optimiser);
|
||||
$this->check_colors($optimiser);
|
||||
$this->check_margins($optimiser);
|
||||
$this->check_padding($optimiser);
|
||||
$this->check_widths($optimiser);
|
||||
|
||||
$this->try_broken_css_found_in_moodle($optimiser);
|
||||
$this->try_invalid_css_handling($optimiser);
|
||||
$this->try_bulk_processing($optimiser);
|
||||
$this->try_break_things($optimiser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Background colour tests
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function check_background(css_optimiser $optimiser) {
|
||||
|
||||
$cssin = '.test {background-color: #123456;}';
|
||||
$cssout = '.test{background:#123456;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {background-image: url(\'test.png\');}';
|
||||
$cssout = '.test{background-image:url(\'test.png\');}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {background: #123456 url(\'test.png\') no-repeat top left;}';
|
||||
$cssout = '.test{background:#123456 url(\'test.png\') no-repeat top left;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {background: url(\'test.png\') no-repeat top left;}.test{background-position: bottom right}.test {background-color:#123456;}';
|
||||
$cssout = '.test{background:#123456 url(\'test.png\') no-repeat bottom right;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {background: url( \'test.png\' )}.test{background: bottom right}.test {background:#123456;}';
|
||||
$cssout = '.test{background-image:url(\'test.png\');background-position:bottom right;background-color:#123456;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {background-color: #123456;background-repeat: repeat-x; background-position: 100% 0%;}';
|
||||
$cssout = '.test{background-color:#123456;background-repeat:repeat-x;background-position:100% 0%;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.tree_item.branch {background-image: url([[pix:t/expanded]]);background-position: 0 10%;background-repeat: no-repeat;}
|
||||
.tree_item.branch.navigation_node {background-image:none;padding-left:0;}';
|
||||
$cssout = '.tree_item.branch{background:url([[pix:t/expanded]]) no-repeat 0 10%;} .tree_item.branch.navigation_node{background-image:none;padding-left:0;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.block_tree .tree_item.emptybranch {background-image: url([[pix:t/collapsed_empty]]);background-position: 0% 5%;background-repeat: no-repeat;}
|
||||
.block_tree .collapsed .tree_item.branch {background-image: url([[pix:t/collapsed]]);}';
|
||||
$cssout = '.block_tree .tree_item.emptybranch{background:url([[pix:t/collapsed_empty]]) no-repeat 0% 5%;} .block_tree .collapsed .tree_item.branch{background-image:url([[pix:t/collapsed]]);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Border tests
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function check_borders(css_optimiser $optimiser) {
|
||||
$cssin = '.test {border: 1px solid #654321} .test {border-bottom-color: #123456}';
|
||||
$cssout = '.test{border:1px solid;border-color:#654321 #654321 #123456;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {border:1px solid red;}';
|
||||
$cssout = '.one{border:1px solid #FF0000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {border:1px solid;} .one {border:2px dotted #DDD;}';
|
||||
$cssout = '.one{border:2px dotted #DDDDDD;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {border:2px dotted #DDD;}.one {border:1px solid;} ';
|
||||
$cssout = '.one{border:1px solid #DDDDDD;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one, .two {border:1px solid red;}';
|
||||
$cssout = ".one, .two{border:1px solid #FF0000;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one, .two {border:0px;}';
|
||||
$cssout = ".one, .two{border-width:0;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one, .two {border-top: 5px solid white;}';
|
||||
$cssout = ".one, .two{border-top:5px solid #FFFFFF;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {border:1px solid red;} .two {border:1px solid red;}';
|
||||
$cssout = ".one, .two{border:1px solid #FF0000;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {border:1px solid red;width:20px;} .two {border:1px solid red;height:20px;}';
|
||||
$cssout = ".one{width:20px;border:1px solid #FF0000;} .two{height:20px;border:1px solid #FF0000;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border: 1px solid #123456;} .test {border-color: #654321}';
|
||||
$cssout = '.test{border:1px solid #654321;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border-width: 1px; border-style: solid; border-color: #123456;}';
|
||||
$cssout = '.test{border:1px solid #123456;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border:1px solid #123456;border-top:2px dotted #654321;}';
|
||||
$cssout = '.test{border:1px solid #123456;border-top:2px dotted #654321;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border:1px solid #123456;border-left:2px dotted #654321;}';
|
||||
$cssout = '.test{border:1px solid #123456;border-left:2px dotted #654321;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border-left:2px dotted #654321;border:1px solid #123456;}';
|
||||
$cssout = '.test{border:1px solid #123456;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border:1px solid;border-top-color:#123456;}';
|
||||
$cssout = '.test{border:1px solid;border-top-color:#123456;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border:1px solid;border-top-color:#111; border-bottom-color: #222;border-left-color: #333;}';
|
||||
$cssout = '.test{border:1px solid;border-top-color:#111;border-bottom-color:#222;border-left-color:#333;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {border:1px solid;border-top-color:#111; border-bottom-color: #222;border-left-color: #333;border-right-color:#444;}';
|
||||
$cssout = '.test{border:1px solid;border-color:#111 #444 #222 #333;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.generaltable .cell {border-color:#EEEEEE;} .generaltable .cell {border-width: 1px;border-style: solid;}';
|
||||
$cssout = '.generaltable .cell{border:1px solid #EEEEEE;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '#page-admin-roles-override .rolecap {border:none;border-bottom:1px solid #CECECE;}';
|
||||
$cssout = '#page-admin-roles-override .rolecap{border-top:0;border-right:0;border-bottom:1px solid #CECECE;border-left:0;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test colour styles
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function check_colors(css_optimiser $optimiser) {
|
||||
$css = '.css{}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = '.css{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = '#some{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div.css{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div#some{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div[type=blah]{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div.css[type=blah]{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div#some[type=blah]{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = '#some.css[type=blah]{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = '#some .css[type=blah]{color:#123456;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$cssin = '.one {color:red;} .two {color:#F00;}';
|
||||
$cssout = ".one, .two{color:#F00;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:#123;color:#321;}';
|
||||
$cssout = '.one{color:#321;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:#123; color : #321 ;}';
|
||||
$cssout = '.one{color:#321;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:#123;} .one {color:#321;}';
|
||||
$cssout = '.one{color:#321;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:#123 !important;color:#321;}';
|
||||
$cssout = '.one{color:#123 !important;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:#123 !important;} .one {color:#321;}';
|
||||
$cssout = '.one{color:#123 !important;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:rgb(255, 128, 1)}';
|
||||
$cssout = '.one{color:rgb(255, 128, 1);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:rgba(255, 128, 1, 0.5)}';
|
||||
$cssout = '.one{color:rgba(255, 128, 1, 0.5);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:hsl(120, 65%, 75%)}';
|
||||
$cssout = '.one{color:hsl(120, 65%, 75%);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:hsla(120,65%,75%,0.5)}';
|
||||
$cssout = '.one{color:hsla(120,65%,75%,0.5);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Try some invalid colours to make sure we don't mangle them.
|
||||
$css = 'div#some{color:#1;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div#some{color:#12;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div#some{color:#1234;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
|
||||
$css = 'div#some{color:#12345;}';
|
||||
$this->assertEquals($css, $optimiser->process($css));
|
||||
}
|
||||
|
||||
protected function check_widths(css_optimiser $optimiser) {
|
||||
$cssin = '.css {width:0}';
|
||||
$cssout = '.css{width:0;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.css {width:0px}';
|
||||
$cssout = '.css{width:0;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.css {width:0em}';
|
||||
$cssout = '.css{width:0;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.css {width:0pt}';
|
||||
$cssout = '.css{width:0;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.css {width:0mm}';
|
||||
$cssout = '.css{width:0;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.css {width:100px}';
|
||||
$cssout = '.css{width:100px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test margin styles
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function check_margins(css_optimiser $optimiser) {
|
||||
$cssin = '.one {margin: 1px 2px 3px 4px}';
|
||||
$cssout = '.one{margin:1px 2px 3px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin-top:1px; margin-left:4px; margin-right:2px; margin-bottom: 3px;}';
|
||||
$cssout = '.one{margin:1px 2px 3px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin-top:1px; margin-left:4px;}';
|
||||
$cssout = '.one{margin-top:1px;margin-left:4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin:1px; margin-left:4px;}';
|
||||
$cssout = '.one{margin:1px 1px 1px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin:1px; margin-bottom:4px;}';
|
||||
$cssout = '.one{margin:1px 1px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one, .two, .one.two, .one .two {margin:0;} .one.two {margin:0 7px;}';
|
||||
$cssout = '.one, .two, .one .two{margin:0;} .one.two{margin:0 7px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test padding styles
|
||||
*
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function check_padding(css_optimiser $optimiser) {
|
||||
$cssin = '.one {margin: 1px 2px 3px 4px}';
|
||||
$cssout = '.one{margin:1px 2px 3px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin-top:1px; margin-left:4px; margin-right:2px; margin-bottom: 3px;}';
|
||||
$cssout = '.one{margin:1px 2px 3px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin-top:1px; margin-left:4px;}';
|
||||
$cssout = '.one{margin-top:1px;margin-left:4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin:1px; margin-left:4px;}';
|
||||
$cssout = '.one{margin:1px 1px 1px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin:1px; margin-bottom:4px;}';
|
||||
$cssout = '.one{margin:1px 1px 4px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {margin:0 !important;}';
|
||||
$cssout = '.one{margin:0 !important;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {padding:0 !important;}';
|
||||
$cssout = '.one{padding:0 !important;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one, .two, .one.two, .one .two {margin:0;} .one.two {margin:0 7px;}';
|
||||
$cssout = '.one, .two, .one .two{margin:0;} .one.two{margin:0 7px;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test some totally invalid CSS optimisation
|
||||
*
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function try_invalid_css_handling(css_optimiser $optimiser) {
|
||||
|
||||
$cssin = array(
|
||||
'.one{}',
|
||||
'.one {:}',
|
||||
'.one {;}',
|
||||
'.one {;;;;;}',
|
||||
'.one {:;}',
|
||||
'.one {:;:;:;:::;;;}',
|
||||
'.one {!important}',
|
||||
'.one {:!important}',
|
||||
'.one {:!important;}',
|
||||
'.one {;!important}'
|
||||
);
|
||||
$cssout = '.one{}';
|
||||
foreach ($cssin as $css) {
|
||||
$this->assertEquals($cssout, $optimiser->process($css));
|
||||
}
|
||||
|
||||
$cssin = array(
|
||||
'.one{background-color:red;}',
|
||||
'.one {background-color:red;} .one {background-color:}',
|
||||
'.one {background-color:red;} .one {background-color;}',
|
||||
'.one {background-color:red;} .one {background-color}',
|
||||
'.one {background-color:red;} .one {background-color:;}',
|
||||
'.one {background-color:red;} .one {:blue;}',
|
||||
'.one {background-color:red;} .one {:#00F}',
|
||||
);
|
||||
$cssout = '.one{background:#F00;}';
|
||||
foreach ($cssin as $css) {
|
||||
$this->assertEquals($cssout, $optimiser->process($css));
|
||||
}
|
||||
|
||||
$cssin = '..one {background-color:color:red}';
|
||||
$cssout = '..one{background-color:color:red;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '#.one {background-color:color:red}';
|
||||
$cssout = '#.one{background-color:color:red;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '##one {background-color:color:red}';
|
||||
$cssout = '##one{background-color:color:red;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {background-color:color:red}';
|
||||
$cssout = '.one{background-color:color:red;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {background-color:red;color;border-color:blue}';
|
||||
$cssout = '.one{background:#F00;border-color:#00F;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '{background-color:#123456;color:red;}{color:green;}';
|
||||
$cssout = "{color:#008000;background:#123456;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.one {color:red;} {color:green;} .one {background-color:blue;}';
|
||||
$cssout = ".one{color:#F00;background:#00F;} {color:#008000;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to break some things
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function try_break_things(css_optimiser $optimiser) {
|
||||
// Wildcard test
|
||||
$cssin = '* {color: black;}';
|
||||
$cssout = '*{color:#000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Wildcard test
|
||||
$cssin = '.one * {color: black;}';
|
||||
$cssout = '.one *{color:#000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Wildcard test
|
||||
$cssin = '* .one * {color: black;}';
|
||||
$cssout = '* .one *{color:#000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Wildcard test
|
||||
$cssin = '*,* {color: black;}';
|
||||
$cssout = '*{color:#000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Wildcard test
|
||||
$cssin = '*, * .one {color: black;}';
|
||||
$cssout = "*,\n* .one{color:#000;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Wildcard test
|
||||
$cssin = '*, *.one {color: black;}';
|
||||
$cssout = "*,\n*.one{color:#000;}";
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Psedo test
|
||||
$cssin = '.one:before {color: black;}';
|
||||
$cssout = '.one:before{color:#000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Psedo test
|
||||
$cssin = '.one:after {color: black;}';
|
||||
$cssout = '.one:after{color:#000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Psedo test
|
||||
$cssin = '.one:onclick {color: black;}';
|
||||
$cssout = '.one:onclick{color:#000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Test complex CSS rules that don't really exist but mimic other CSS rules
|
||||
$cssin = '.one {master-of-destruction: explode(\' \', "What madness";}';
|
||||
$cssout = '.one{master-of-destruction:explode(\' \', "What madness";}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Test some complex IE css... I couldn't even think of a more complext solution
|
||||
// than the CSS they came up with.
|
||||
$cssin = 'a { opacity: 0.5; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; filter: alpha(opacity=50); }';
|
||||
$cssout = 'a{opacity:0.5;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";filter:alpha(opacity=50);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
|
||||
/**
|
||||
* A bulk processing test
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
protected function try_bulk_processing(css_optimiser $optimiser) {
|
||||
global $CFG;
|
||||
$cssin = <<<CSS
|
||||
.test .one {
|
||||
margin:5px;
|
||||
border:0;
|
||||
}
|
||||
.test .one {
|
||||
margin: 10px;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.test.one {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
#test .one {margin: 20px;}
|
||||
#test #one {margin: 25px;}.test #one {margin: 30px;}
|
||||
.test .one { background-color: #123; }
|
||||
.test.one{border:1px solid blue}.test.one{border-color:green;}
|
||||
|
||||
@media print {
|
||||
#test .one {margin: 35px;}
|
||||
}
|
||||
|
||||
@media print {
|
||||
#test .one {margin: 40px;color: #123456;}
|
||||
#test #one {margin: 45px;}
|
||||
}
|
||||
|
||||
@media print,screen {
|
||||
#test .one {color: #654321;}
|
||||
}
|
||||
|
||||
#test .one,
|
||||
#new.style {color:#000;}
|
||||
CSS;
|
||||
|
||||
$cssout = <<<CSS
|
||||
.test .one{color:#F00;margin:10px;border-width:0;background:#123;}
|
||||
.test.one{margin:15px;border:1px solid #008000;}
|
||||
#test .one{color:#000;margin:20px;}
|
||||
#test #one{margin:25px;}
|
||||
.test #one{margin:30px;}
|
||||
#new.style{color:#000;}
|
||||
|
||||
|
||||
@media print {
|
||||
#test .one{color:#123456;margin:40px;}
|
||||
#test #one{margin:45px;}
|
||||
}
|
||||
|
||||
@media print,screen {
|
||||
#test .one{color:#654321;}
|
||||
}
|
||||
CSS;
|
||||
$CFG->cssoptimiserpretty = 1;
|
||||
$this->assertEquals($optimiser->process($cssin), $cssout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CSS colour matching
|
||||
*/
|
||||
public function test_css_is_colour() {
|
||||
// First lets test hex colours
|
||||
$this->assertTrue(css_is_colour('#123456'));
|
||||
$this->assertTrue(css_is_colour('#123'));
|
||||
$this->assertTrue(css_is_colour('#ABCDEF'));
|
||||
$this->assertTrue(css_is_colour('#ABC'));
|
||||
$this->assertTrue(css_is_colour('#abcdef'));
|
||||
$this->assertTrue(css_is_colour('#abc'));
|
||||
$this->assertTrue(css_is_colour('#aBcDeF'));
|
||||
$this->assertTrue(css_is_colour('#aBc'));
|
||||
$this->assertTrue(css_is_colour('#1a2Bc3'));
|
||||
$this->assertTrue(css_is_colour('#1Ac'));
|
||||
|
||||
// Note the following two colour's arn't really colours but browsers process
|
||||
// them still.
|
||||
$this->assertTrue(css_is_colour('#A'));
|
||||
$this->assertTrue(css_is_colour('#12'));
|
||||
// Having four or five characters however are not valid colours and
|
||||
// browsers don't parse them. They need to fail so that broken CSS
|
||||
// stays broken after optimisation.
|
||||
$this->assertFalse(css_is_colour('#1234'));
|
||||
$this->assertFalse(css_is_colour('#12345'));
|
||||
|
||||
$this->assertFalse(css_is_colour('#BCDEFG'));
|
||||
$this->assertFalse(css_is_colour('#'));
|
||||
$this->assertFalse(css_is_colour('#0000000'));
|
||||
$this->assertFalse(css_is_colour('#132-245'));
|
||||
$this->assertFalse(css_is_colour('#13 23 43'));
|
||||
$this->assertFalse(css_is_colour('123456'));
|
||||
|
||||
// Next lets test real browser mapped colours
|
||||
$this->assertTrue(css_is_colour('black'));
|
||||
$this->assertTrue(css_is_colour('blue'));
|
||||
$this->assertTrue(css_is_colour('BLACK'));
|
||||
$this->assertTrue(css_is_colour('Black'));
|
||||
$this->assertTrue(css_is_colour('bLACK'));
|
||||
$this->assertTrue(css_is_colour('mediumaquamarine'));
|
||||
$this->assertTrue(css_is_colour('mediumAquamarine'));
|
||||
$this->assertFalse(css_is_colour('monkey'));
|
||||
$this->assertFalse(css_is_colour(''));
|
||||
$this->assertFalse(css_is_colour('not a colour'));
|
||||
|
||||
// Next lets test rgb(a) colours
|
||||
$this->assertTrue(css_is_colour('rgb(255,255,255)'));
|
||||
$this->assertTrue(css_is_colour('rgb(0, 0, 0)'));
|
||||
$this->assertTrue(css_is_colour('RGB (255, 255 , 255)'));
|
||||
$this->assertTrue(css_is_colour('rgba(0,0,0,0)'));
|
||||
$this->assertTrue(css_is_colour('RGBA(255,255,255,1)'));
|
||||
$this->assertTrue(css_is_colour('rgbA(255,255,255,0.5)'));
|
||||
$this->assertFalse(css_is_colour('rgb(-255,-255,-255)'));
|
||||
$this->assertFalse(css_is_colour('rgb(256,-256,256)'));
|
||||
|
||||
// Now lets test HSL colours
|
||||
$this->assertTrue(css_is_colour('hsl(0,0%,100%)'));
|
||||
$this->assertTrue(css_is_colour('hsl(180, 0%, 10%)'));
|
||||
$this->assertTrue(css_is_colour('hsl (360, 100% , 95%)'));
|
||||
|
||||
// Finally test the special values
|
||||
$this->assertTrue(css_is_colour('inherit'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the css_is_width function
|
||||
*/
|
||||
public function test_css_is_width() {
|
||||
|
||||
$this->assertTrue(css_is_width('0'));
|
||||
$this->assertTrue(css_is_width('0px'));
|
||||
$this->assertTrue(css_is_width('0em'));
|
||||
$this->assertTrue(css_is_width('199px'));
|
||||
$this->assertTrue(css_is_width('199em'));
|
||||
$this->assertTrue(css_is_width('199%'));
|
||||
$this->assertTrue(css_is_width('-1'));
|
||||
$this->assertTrue(css_is_width('-1px'));
|
||||
$this->assertTrue(css_is_width('auto'));
|
||||
$this->assertTrue(css_is_width('inherit'));
|
||||
|
||||
$this->assertFalse(css_is_width('-'));
|
||||
$this->assertFalse(css_is_width('bananas'));
|
||||
$this->assertFalse(css_is_width(''));
|
||||
$this->assertFalse(css_is_width('top'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function tests some of the broken crazy CSS we have in Moodle.
|
||||
* For each of these things the value needs to be corrected if we can be 100%
|
||||
* certain what is going wrong, Or it needs to be left as is.
|
||||
*
|
||||
* @param css_optimiser $optimiser
|
||||
*/
|
||||
public function try_broken_css_found_in_moodle(css_optimiser $optimiser) {
|
||||
// Notice how things are out of order here but that they get corrected
|
||||
$cssin = '.test {background:url([[pix:theme|pageheaderbgred]]) top center no-repeat}';
|
||||
$cssout = '.test{background:url([[pix:theme|pageheaderbgred]]) no-repeat top center;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Cursor hand isn't valid
|
||||
$cssin = '.test {cursor: hand;}';
|
||||
$cssout = '.test{cursor:hand;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Zoom property isn't valid
|
||||
$cssin = '.test {zoom: 1;}';
|
||||
$cssout = '.test{zoom:1;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Left isn't a valid position property
|
||||
$cssin = '.test {position: left;}';
|
||||
$cssout = '.test{position:left;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// The dark red color isn't a valid HTML color but has a standardised
|
||||
// translation of #8B0000
|
||||
$cssin = '.test {color: darkred;}';
|
||||
$cssout = '.test{color:#8B0000;}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// You can't use argb colours as border colors
|
||||
$cssin = '.test {border-bottom: 1px solid rgba(0,0,0,0.25);}';
|
||||
$cssout = '.test{border-bottom:1px solid rgba(0,0,0,0.25);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
// Opacity with annoying IE equivilants....
|
||||
$cssin = '.test {opacity: 0.5; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; filter: alpha(opacity=50);}';
|
||||
$cssout = '.test{opacity:0.5;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";filter:alpha(opacity=50);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
<?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 events subsystems
|
||||
*
|
||||
* @package core
|
||||
* @subpackage event
|
||||
* @copyright 2007 onwards Martin Dougiamas (http://dougiamas.com)
|
||||
* @author Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// test handler function
|
||||
function sample_function_handler($eventdata) {
|
||||
static $called = 0;
|
||||
static $ignorefail = false;
|
||||
|
||||
if ($eventdata == 'status') {
|
||||
return $called;
|
||||
|
||||
} else if ($eventdata == 'reset') {
|
||||
$called = 0;
|
||||
$ignorefail = false;
|
||||
return;
|
||||
|
||||
} else if ($eventdata == 'fail') {
|
||||
if ($ignorefail) {
|
||||
$called++;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if ($eventdata == 'ignorefail') {
|
||||
$ignorefail = true;
|
||||
return;
|
||||
|
||||
} else if ($eventdata == 'ok') {
|
||||
$called++;
|
||||
return true;
|
||||
}
|
||||
|
||||
print_error('invalideventdata', '', '', $eventdata);
|
||||
}
|
||||
|
||||
// test handler class with static method
|
||||
class sample_handler_class {
|
||||
static function static_method($eventdata) {
|
||||
static $called = 0;
|
||||
static $ignorefail = false;
|
||||
|
||||
if ($eventdata == 'status') {
|
||||
return $called;
|
||||
|
||||
} else if ($eventdata == 'reset') {
|
||||
$called = 0;
|
||||
$ignorefail = false;
|
||||
return;
|
||||
|
||||
} else if ($eventdata == 'fail') {
|
||||
if ($ignorefail) {
|
||||
$called++;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if ($eventdata == 'ignorefail') {
|
||||
$ignorefail = true;
|
||||
return;
|
||||
|
||||
} else if ($eventdata == 'ok') {
|
||||
$called++;
|
||||
return true;
|
||||
}
|
||||
|
||||
print_error('invalideventdata', '', '', $eventdata);
|
||||
}
|
||||
}
|
||||
|
||||
class eventslib_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Create temporary entries in the database for these tests.
|
||||
* These tests have to work no matter the data currently in the database
|
||||
* (meaning they should run on a brand new site). This means several items of
|
||||
* data have to be artificially inseminated (:-) in the DB.
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
// Set global category settings to -1 (not force)
|
||||
sample_function_handler('reset');
|
||||
sample_handler_class::static_method('reset');
|
||||
events_update_definition('unittest');
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete temporary entries from the database
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown() {
|
||||
events_uninstall('unittest');
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the installation of event handlers from file
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_update_definition__install() {
|
||||
global $CFG, $DB;
|
||||
|
||||
$dbcount = $DB->count_records('events_handlers', array('component'=>'unittest'));
|
||||
$handlers = array();
|
||||
require(__DIR__.'/fixtures/events.php');
|
||||
$filecount = count($handlers);
|
||||
$this->assertEquals($dbcount, $filecount, 'Equal number of handlers in file and db: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the uninstallation of event handlers from file
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_update_definition__uninstall() {
|
||||
global $DB;
|
||||
|
||||
events_uninstall('unittest');
|
||||
$this->assertEquals(0, $DB->count_records('events_handlers', array('component'=>'unittest')), 'All handlers should be uninstalled: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the update of event handlers from file
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_update_definition__update() {
|
||||
global $DB;
|
||||
// first modify directly existing handler
|
||||
$handler = $DB->get_record('events_handlers', array('component'=>'unittest', 'eventname'=>'test_instant'));
|
||||
|
||||
$original = $handler->handlerfunction;
|
||||
|
||||
// change handler in db
|
||||
$DB->set_field('events_handlers', 'handlerfunction', serialize('some_other_function_handler'), array('id'=>$handler->id));
|
||||
|
||||
// update the definition, it should revert the handler back
|
||||
events_update_definition('unittest');
|
||||
$handler = $DB->get_record('events_handlers', array('component'=>'unittest', 'eventname'=>'test_instant'));
|
||||
$this->assertEquals($handler->handlerfunction, $original, 'update should sync db with file definition: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* tests events_trigger_is_registered funtion()
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_is_registered() {
|
||||
$this->assertTrue(events_is_registered('test_instant', 'unittest'));
|
||||
}
|
||||
|
||||
/**
|
||||
* tests events_trigger funtion()
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_trigger__instant() {
|
||||
$this->assertEquals(0, events_trigger('test_instant', 'ok'));
|
||||
$this->assertEquals(0, events_trigger('test_instant', 'ok'));
|
||||
$this->assertEquals(2, sample_function_handler('status'));
|
||||
}
|
||||
|
||||
/**
|
||||
* tests events_trigger funtion()
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_trigger__cron() {
|
||||
$this->assertEquals(0, events_trigger('test_cron', 'ok'));
|
||||
$this->assertEquals(0, sample_handler_class::static_method('status'));
|
||||
events_cron('test_cron');
|
||||
$this->assertEquals(1, sample_handler_class::static_method('status'));
|
||||
}
|
||||
|
||||
/**
|
||||
* tests events_pending_count()
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_pending_count() {
|
||||
events_trigger('test_cron', 'ok');
|
||||
events_trigger('test_cron', 'ok');
|
||||
events_cron('test_cron');
|
||||
$this->assertEquals(0, events_pending_count('test_cron'), 'all messages should be already dequeued: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* tests events_trigger funtion() when instant handler fails
|
||||
* @return void
|
||||
*/
|
||||
public function test_events_trigger__failed_instant() {
|
||||
$this->assertEquals(1, events_trigger('test_instant', 'fail'), 'fail first event: %s');
|
||||
$this->assertEquals(1, events_trigger('test_instant', 'ok'), 'this one should fail too: %s');
|
||||
$this->assertEquals(0, events_cron('test_instant'), 'all events should stay in queue: %s');
|
||||
$this->assertEquals(2, events_pending_count('test_instant'), 'two events should in queue: %s');
|
||||
$this->assertEquals(0, sample_function_handler('status'), 'verify no event dispatched yet: %s');
|
||||
sample_function_handler('ignorefail'); //ignore "fail" eventdata from now on
|
||||
$this->assertEquals(1, events_trigger('test_instant', 'ok'), 'this one should go to queue directly: %s');
|
||||
$this->assertEquals(3, events_pending_count('test_instant'), 'three events should in queue: %s');
|
||||
$this->assertEquals(0, sample_function_handler('status'), 'verify previous event was not dispatched: %s');
|
||||
$this->assertEquals(3, events_cron('test_instant'), 'all events should be dispatched: %s');
|
||||
$this->assertEquals(3, sample_function_handler('status'), 'verify three events were dispatched: %s');
|
||||
$this->assertEquals(0, events_pending_count('test_instant'), 'no events should in queue: %s');
|
||||
$this->assertEquals(0, events_trigger('test_instant', 'ok'), 'this event should be dispatched immediately: %s');
|
||||
$this->assertEquals(4, sample_function_handler('status'), 'verify event was dispatched: %s');
|
||||
$this->assertEquals(0, events_pending_count('test_instant'), 'no events should in queue: %s');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for /lib/externallib.php.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage phpunit
|
||||
* @copyright 2009 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/externallib.php');
|
||||
|
||||
|
||||
class externallib_test extends UnitTestCase {
|
||||
public function test_validate_params() {
|
||||
$params = array('text'=>'aaa', 'someid'=>'6',);
|
||||
$description = new external_function_parameters(array('someid' => new external_value(PARAM_INT, 'Some int value'),
|
||||
'text' => new external_value(PARAM_ALPHA, 'Some text value')));
|
||||
$result = external_api::validate_parameters($description, $params);
|
||||
$this->assertEquals(count($result), 2);
|
||||
reset($result);
|
||||
$this->assertTrue(key($result) === 'someid');
|
||||
$this->assertTrue($result['someid'] === 6);
|
||||
$this->assertTrue($result['text'] === 'aaa');
|
||||
|
||||
|
||||
$params = array('someids'=>array('1', 2, 'a'=>'3'), 'scalar'=>666);
|
||||
$description = new external_function_parameters(array('someids' => new external_multiple_structure(new external_value(PARAM_INT, 'Some ID')),
|
||||
'scalar' => new external_value(PARAM_ALPHANUM, 'Some text value')));
|
||||
$result = external_api::validate_parameters($description, $params);
|
||||
$this->assertEquals(count($result), 2);
|
||||
reset($result);
|
||||
$this->assertTrue(key($result) === 'someids');
|
||||
$this->assertTrue($result['someids'] == array(0=>1, 1=>2, 2=>3));
|
||||
$this->assertTrue($result['scalar'] === '666');
|
||||
|
||||
|
||||
$params = array('text'=>'aaa');
|
||||
$description = new external_function_parameters(array('someid' => new external_value(PARAM_INT, 'Some int value', false),
|
||||
'text' => new external_value(PARAM_ALPHA, 'Some text value')));
|
||||
$result = external_api::validate_parameters($description, $params);
|
||||
$this->assertEquals(count($result), 2);
|
||||
reset($result);
|
||||
$this->assertTrue(key($result) === 'someid');
|
||||
$this->assertTrue($result['someid'] === null);
|
||||
$this->assertTrue($result['text'] === 'aaa');
|
||||
|
||||
|
||||
$params = array('text'=>'aaa');
|
||||
$description = new external_function_parameters(array('someid' => new external_value(PARAM_INT, 'Some int value', false, 6),
|
||||
'text' => new external_value(PARAM_ALPHA, 'Some text value')));
|
||||
$result = external_api::validate_parameters($description, $params);
|
||||
$this->assertEquals(count($result), 2);
|
||||
reset($result);
|
||||
$this->assertTrue(key($result) === 'someid');
|
||||
$this->assertTrue($result['someid'] === 6);
|
||||
$this->assertTrue($result['text'] === 'aaa');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?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/>.
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for /lib/filelib.php.
|
||||
*
|
||||
* @package core_files
|
||||
* @category phpunit
|
||||
* @copyright 2009 Jerome Mouneyrac
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
|
||||
class filelib_test extends basic_testcase {
|
||||
public function test_format_postdata_for_curlcall() {
|
||||
|
||||
//POST params with just simple types
|
||||
$postdatatoconvert =array( 'userid' => 1, 'roleid' => 22, 'name' => 'john');
|
||||
$expectedresult = "userid=1&roleid=22&name=john";
|
||||
$postdata = format_postdata_for_curlcall($postdatatoconvert);
|
||||
$this->assertEquals($postdata, $expectedresult);
|
||||
|
||||
//POST params with a string containing & character
|
||||
$postdatatoconvert =array( 'name' => 'john&emilie', 'roleid' => 22);
|
||||
$expectedresult = "name=john%26emilie&roleid=22"; //urlencode: '%26' => '&'
|
||||
$postdata = format_postdata_for_curlcall($postdatatoconvert);
|
||||
$this->assertEquals($postdata, $expectedresult);
|
||||
|
||||
//POST params with an empty value
|
||||
$postdatatoconvert =array( 'name' => null, 'roleid' => 22);
|
||||
$expectedresult = "name=&roleid=22";
|
||||
$postdata = format_postdata_for_curlcall($postdatatoconvert);
|
||||
$this->assertEquals($postdata, $expectedresult);
|
||||
|
||||
//POST params with complex types
|
||||
$postdatatoconvert =array( 'users' => array(
|
||||
array(
|
||||
'id' => 2,
|
||||
'customfields' => array(
|
||||
array
|
||||
(
|
||||
'type' => 'Color',
|
||||
'value' => 'violet'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$expectedresult = "users[0][id]=2&users[0][customfields][0][type]=Color&users[0][customfields][0][value]=violet";
|
||||
$postdata = format_postdata_for_curlcall($postdatatoconvert);
|
||||
$this->assertEquals($postdata, $expectedresult);
|
||||
|
||||
//POST params with other complex types
|
||||
$postdatatoconvert = array ('members' =>
|
||||
array(
|
||||
array('groupid' => 1, 'userid' => 1)
|
||||
, array('groupid' => 1, 'userid' => 2)
|
||||
)
|
||||
);
|
||||
$expectedresult = "members[0][groupid]=1&members[0][userid]=1&members[1][groupid]=1&members[1][userid]=2";
|
||||
$postdata = format_postdata_for_curlcall($postdatatoconvert);
|
||||
$this->assertEquals($postdata, $expectedresult);
|
||||
}
|
||||
|
||||
public function test_download_file_content() {
|
||||
$testhtml = "http://download.moodle.org/unittest/test.html";
|
||||
$contents = download_file_content($testhtml);
|
||||
$this->assertEquals('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,767 @@
|
||||
<?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 the parts of ../filterlib.php that involve loading the configuration
|
||||
* from, and saving the configuration to, the database.
|
||||
*
|
||||
* @package core_filter
|
||||
* @category phpunit
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/filterlib.php');
|
||||
|
||||
/**
|
||||
* Test functions that affect filter_active table with contextid = $syscontextid.
|
||||
*/
|
||||
class filter_active_global_test extends advanced_testcase {
|
||||
|
||||
public function setUp() {
|
||||
global $DB;
|
||||
parent::setUp();
|
||||
$DB->delete_records('filter_active', array());
|
||||
$this->resetAfterTest(false);
|
||||
}
|
||||
|
||||
private function assert_only_one_filter_globally($filter, $state) {
|
||||
global $DB;
|
||||
$recs = $DB->get_records('filter_active');
|
||||
$this->assertEquals(1, count($recs), 'More than one record returned %s.');
|
||||
$rec = reset($recs);
|
||||
unset($rec->id);
|
||||
$expectedrec = new stdClass();
|
||||
$expectedrec->filter = $filter;
|
||||
$expectedrec->contextid = context_system::instance()->id;
|
||||
$expectedrec->active = $state;
|
||||
$expectedrec->sortorder = 1;
|
||||
$this->assertEquals($expectedrec, $rec);
|
||||
}
|
||||
|
||||
private function assert_global_sort_order($filters) {
|
||||
global $DB;
|
||||
|
||||
$sortedfilters = $DB->get_records_menu('filter_active',
|
||||
array('contextid' => context_system::instance()->id), 'sortorder', 'sortorder,filter');
|
||||
$testarray = array();
|
||||
$index = 1;
|
||||
foreach($filters as $filter) {
|
||||
$testarray[$index++] = $filter;
|
||||
}
|
||||
$this->assertEquals($testarray, $sortedfilters);
|
||||
}
|
||||
|
||||
public function test_set_filter_globally_on() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON, 1);
|
||||
// Validate.
|
||||
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_ON);
|
||||
}
|
||||
|
||||
public function test_set_filter_globally_off() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_OFF, 1);
|
||||
// Validate.
|
||||
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_OFF);
|
||||
}
|
||||
|
||||
public function test_set_filter_globally_disabled() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_DISABLED, 1);
|
||||
// Validate.
|
||||
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_DISABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_global_config_exception_on_invalid_state() {
|
||||
filter_set_global_state('filter/name', 0, 1);
|
||||
}
|
||||
|
||||
public function test_set_no_sortorder_clash() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/one', TEXTFILTER_DISABLED, 1);
|
||||
filter_set_global_state('filter/two', TEXTFILTER_DISABLED, 1);
|
||||
// Validate - should have pushed other filters down.
|
||||
$this->assert_global_sort_order(array('filter/two', 'filter/one'));
|
||||
}
|
||||
|
||||
public function test_auto_sort_order_disabled() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/one', TEXTFILTER_DISABLED);
|
||||
filter_set_global_state('filter/two', TEXTFILTER_DISABLED);
|
||||
// Validate.
|
||||
$this->assert_global_sort_order(array('filter/one', 'filter/two'));
|
||||
}
|
||||
|
||||
public function test_auto_sort_order_enabled() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/one', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/two', TEXTFILTER_OFF);
|
||||
// Validate.
|
||||
$this->assert_global_sort_order(array('filter/one', 'filter/two'));
|
||||
}
|
||||
|
||||
public function test_auto_sort_order_mixed() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/0', TEXTFILTER_DISABLED);
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/2', TEXTFILTER_DISABLED);
|
||||
filter_set_global_state('filter/3', TEXTFILTER_OFF);
|
||||
// Validate.
|
||||
$this->assert_global_sort_order(array('filter/1', 'filter/3', 'filter/0', 'filter/2'));
|
||||
}
|
||||
|
||||
public function test_update_existing_dont_duplicate() {
|
||||
// Setup fixture.
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/name', TEXTFILTER_OFF);
|
||||
// Validate.
|
||||
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_sort_order_not_too_low() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/2', TEXTFILTER_ON, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_sort_order_not_too_high() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/2', TEXTFILTER_ON, 3);
|
||||
}
|
||||
|
||||
public function test_update_reorder_down() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/2', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/3', TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/2', TEXTFILTER_ON, 1);
|
||||
// Validate.
|
||||
$this->assert_global_sort_order(array('filter/2', 'filter/1', 'filter/3'));
|
||||
}
|
||||
|
||||
public function test_update_reorder_up() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/2', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/3', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/4', TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/2', TEXTFILTER_ON, 3);
|
||||
// Validate.
|
||||
$this->assert_global_sort_order(array('filter/1', 'filter/3', 'filter/2', 'filter/4'));
|
||||
}
|
||||
|
||||
public function test_auto_sort_order_change_to_enabled() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/2', TEXTFILTER_DISABLED);
|
||||
filter_set_global_state('filter/3', TEXTFILTER_DISABLED);
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/3', TEXTFILTER_ON);
|
||||
// Validate.
|
||||
$this->assert_global_sort_order(array('filter/1', 'filter/3', 'filter/2'));
|
||||
}
|
||||
|
||||
public function test_auto_sort_order_change_to_disabled() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/2', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/3', TEXTFILTER_DISABLED);
|
||||
// Exercise SUT.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_DISABLED);
|
||||
// Validate.
|
||||
$this->assert_global_sort_order(array('filter/2', 'filter/1', 'filter/3'));
|
||||
}
|
||||
|
||||
public function test_filter_get_global_states() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/1', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/2', TEXTFILTER_OFF);
|
||||
filter_set_global_state('filter/3', TEXTFILTER_DISABLED);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_global_states();
|
||||
// Validate.
|
||||
$this->assertEquals(array(
|
||||
'filter/1' => (object) array('filter' => 'filter/1', 'active' => TEXTFILTER_ON, 'sortorder' => 1),
|
||||
'filter/2' => (object) array('filter' => 'filter/2', 'active' => TEXTFILTER_OFF, 'sortorder' => 2),
|
||||
'filter/3' => (object) array('filter' => 'filter/3', 'active' => TEXTFILTER_DISABLED, 'sortorder' => 3)
|
||||
), $filters);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test functions that affect filter_active table with contextid = $syscontextid.
|
||||
*/
|
||||
class filter_active_local_test extends advanced_testcase {
|
||||
|
||||
public function setUp() {
|
||||
global $DB;
|
||||
parent::setUp();
|
||||
$DB->delete_records('filter_active', array());
|
||||
$this->resetAfterTest(false);
|
||||
}
|
||||
|
||||
private function assert_only_one_local_setting($filter, $contextid, $state) {
|
||||
global $DB;
|
||||
$recs = $DB->get_records('filter_active');
|
||||
$this->assertEquals(1, count($recs), 'More than one record returned %s.');
|
||||
$rec = reset($recs);
|
||||
unset($rec->id);
|
||||
unset($rec->sortorder);
|
||||
$expectedrec = new stdClass();
|
||||
$expectedrec->filter = $filter;
|
||||
$expectedrec->contextid = $contextid;
|
||||
$expectedrec->active = $state;
|
||||
$this->assertEquals($expectedrec, $rec);
|
||||
}
|
||||
|
||||
private function assert_no_local_setting() {
|
||||
global $DB;
|
||||
$this->assertEquals(0, $DB->count_records('filter_active'));
|
||||
}
|
||||
|
||||
public function test_local_on() {
|
||||
// Exercise SUT.
|
||||
filter_set_local_state('filter/name', 123, TEXTFILTER_ON);
|
||||
// Validate.
|
||||
$this->assert_only_one_local_setting('filter/name', 123, TEXTFILTER_ON);
|
||||
}
|
||||
|
||||
public function test_local_off() {
|
||||
// Exercise SUT.
|
||||
filter_set_local_state('filter/name', 123, TEXTFILTER_OFF);
|
||||
// Validate.
|
||||
$this->assert_only_one_local_setting('filter/name', 123, TEXTFILTER_OFF);
|
||||
}
|
||||
|
||||
public function test_local_inherit() {
|
||||
// Exercise SUT.
|
||||
filter_set_local_state('filter/name', 123, TEXTFILTER_INHERIT);
|
||||
// Validate.
|
||||
$this->assert_no_local_setting();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_local_invalid_state_throws_exception() {
|
||||
// Exercise SUT.
|
||||
filter_set_local_state('filter/name', 123, -9999);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_throws_exception_when_setting_global() {
|
||||
// Exercise SUT.
|
||||
filter_set_local_state('filter/name', get_context_instance(CONTEXT_SYSTEM)->id, TEXTFILTER_INHERIT);
|
||||
}
|
||||
|
||||
public function test_local_inherit_deletes_existing() {
|
||||
// Setup fixture.
|
||||
filter_set_local_state('filter/name', 123, TEXTFILTER_INHERIT);
|
||||
// Exercise SUT.
|
||||
filter_set_local_state('filter/name', 123, TEXTFILTER_INHERIT);
|
||||
// Validate.
|
||||
$this->assert_no_local_setting();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test functions that use just the filter_config table.
|
||||
*/
|
||||
class filter_config_test extends advanced_testcase {
|
||||
|
||||
public function setUp() {
|
||||
global $DB;
|
||||
parent::setUp();
|
||||
$DB->delete_records('filter_config', array());
|
||||
$this->resetAfterTest(false);
|
||||
}
|
||||
|
||||
private function assert_only_one_config($filter, $context, $name, $value) {
|
||||
global $DB;
|
||||
$recs = $DB->get_records('filter_config');
|
||||
$this->assertEquals(1, count($recs), 'More than one record returned %s.');
|
||||
$rec = reset($recs);
|
||||
unset($rec->id);
|
||||
$expectedrec = new stdClass();
|
||||
$expectedrec->filter = $filter;
|
||||
$expectedrec->contextid = $context;
|
||||
$expectedrec->name = $name;
|
||||
$expectedrec->value = $value;
|
||||
$this->assertEquals($expectedrec, $rec);
|
||||
}
|
||||
|
||||
public function test_set_new_config() {
|
||||
// Exercise SUT.
|
||||
filter_set_local_config('filter/name', 123, 'settingname', 'An arbitrary value');
|
||||
// Validate.
|
||||
$this->assert_only_one_config('filter/name', 123, 'settingname', 'An arbitrary value');
|
||||
}
|
||||
|
||||
public function test_update_existing_config() {
|
||||
// Setup fixture.
|
||||
filter_set_local_config('filter/name', 123, 'settingname', 'An arbitrary value');
|
||||
// Exercise SUT.
|
||||
filter_set_local_config('filter/name', 123, 'settingname', 'A changed value');
|
||||
// Validate.
|
||||
$this->assert_only_one_config('filter/name', 123, 'settingname', 'A changed value');
|
||||
}
|
||||
|
||||
public function test_filter_get_local_config() {
|
||||
// Setup fixture.
|
||||
filter_set_local_config('filter/name', 123, 'setting1', 'An arbitrary value');
|
||||
filter_set_local_config('filter/name', 123, 'setting2', 'Another arbitrary value');
|
||||
filter_set_local_config('filter/name', 122, 'settingname', 'Value from another context');
|
||||
filter_set_local_config('filter/other', 123, 'settingname', 'Someone else\'s value');
|
||||
// Exercise SUT.
|
||||
$config = filter_get_local_config('filter/name', 123);
|
||||
// Validate.
|
||||
$this->assertEquals(array('setting1' => 'An arbitrary value', 'setting2' => 'Another arbitrary value'), $config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class filter_get_active_available_in_context_test extends advanced_testcase {
|
||||
private static $syscontext;
|
||||
private static $childcontext;
|
||||
private static $childcontext2;
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
$course = self::getDataGenerator()->create_course(array('category'=>1));
|
||||
|
||||
self::$childcontext = context_coursecat::instance(1);
|
||||
self::$childcontext2 = context_course::instance($course->id);
|
||||
self::$syscontext = context_system::instance();
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
global $DB;
|
||||
parent::setUp();
|
||||
|
||||
$DB->delete_records('filter_active', array());
|
||||
$DB->delete_records('filter_config', array());
|
||||
$this->resetAfterTest(false);
|
||||
}
|
||||
|
||||
private function assert_filter_list($expectedfilters, $filters) {
|
||||
$this->assertEquals($expectedfilters, array_keys($filters), '', 0, 10, true);
|
||||
}
|
||||
|
||||
public function test_globally_on_is_returned() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$syscontext);
|
||||
// Validate.
|
||||
$this->assert_filter_list(array('filter/name'), $filters);
|
||||
// Check no config returned correctly.
|
||||
$this->assertEquals(array(), $filters['filter/name']);
|
||||
}
|
||||
|
||||
public function test_globally_off_not_returned() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_OFF);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$childcontext2);
|
||||
// Validate.
|
||||
$this->assert_filter_list(array(), $filters);
|
||||
}
|
||||
|
||||
public function test_globally_off_overridden() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_OFF);
|
||||
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$childcontext2);
|
||||
// Validate.
|
||||
$this->assert_filter_list(array('filter/name'), $filters);
|
||||
}
|
||||
|
||||
public function test_globally_on_overridden() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_OFF);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$childcontext2);
|
||||
// Validate.
|
||||
$this->assert_filter_list(array(), $filters);
|
||||
}
|
||||
|
||||
public function test_globally_disabled_not_overridden() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_DISABLED);
|
||||
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$syscontext);
|
||||
// Validate.
|
||||
$this->assert_filter_list(array(), $filters);
|
||||
}
|
||||
|
||||
public function test_single_config_returned() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value');
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$childcontext);
|
||||
// Validate.
|
||||
$this->assertEquals(array('settingname' => 'A value'), $filters['filter/name']);
|
||||
}
|
||||
|
||||
public function test_multi_config_returned() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value');
|
||||
filter_set_local_config('filter/name', self::$childcontext->id, 'anothersettingname', 'Another value');
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$childcontext);
|
||||
// Validate.
|
||||
$this->assertEquals(array('settingname' => 'A value', 'anothersettingname' => 'Another value'), $filters['filter/name']);
|
||||
}
|
||||
|
||||
public function test_config_from_other_context_not_returned() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value');
|
||||
filter_set_local_config('filter/name', self::$childcontext2->id, 'anothersettingname', 'Another value');
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$childcontext2);
|
||||
// Validate.
|
||||
$this->assertEquals(array('anothersettingname' => 'Another value'), $filters['filter/name']);
|
||||
}
|
||||
|
||||
public function test_config_from_other_filter_not_returned() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value');
|
||||
filter_set_local_config('filter/other', self::$childcontext->id, 'anothersettingname', 'Another value');
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_active_in_context(self::$childcontext);
|
||||
// Validate.
|
||||
$this->assertEquals(array('settingname' => 'A value'), $filters['filter/name']);
|
||||
}
|
||||
|
||||
protected function assert_one_available_filter($filter, $localstate, $inheritedstate, $filters) {
|
||||
$this->assertEquals(1, count($filters), 'More than one record returned %s.');
|
||||
$rec = $filters[$filter];
|
||||
unset($rec->id);
|
||||
$expectedrec = new stdClass();
|
||||
$expectedrec->filter = $filter;
|
||||
$expectedrec->localstate = $localstate;
|
||||
$expectedrec->inheritedstate = $inheritedstate;
|
||||
$this->assertEquals($expectedrec, $rec);
|
||||
}
|
||||
|
||||
public function test_available_in_context_localoverride() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_OFF);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_available_in_context(self::$childcontext);
|
||||
// Validate.
|
||||
$this->assert_one_available_filter('filter/name', TEXTFILTER_OFF, TEXTFILTER_ON, $filters);
|
||||
}
|
||||
|
||||
public function test_available_in_context_nolocaloverride() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_OFF);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_available_in_context(self::$childcontext2);
|
||||
// Validate.
|
||||
$this->assert_one_available_filter('filter/name', TEXTFILTER_INHERIT, TEXTFILTER_OFF, $filters);
|
||||
}
|
||||
|
||||
public function test_available_in_context_disabled_not_returned() {
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_DISABLED);
|
||||
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_ON);
|
||||
// Exercise SUT.
|
||||
$filters = filter_get_available_in_context(self::$childcontext);
|
||||
// Validate.
|
||||
$this->assertEquals(array(), $filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
public function test_available_in_context_exception_with_syscontext() {
|
||||
// Exercise SUT.
|
||||
filter_get_available_in_context(self::$syscontext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class filter_preload_activities_test extends advanced_testcase {
|
||||
private static $syscontext;
|
||||
private static $catcontext;
|
||||
private static $coursecontext;
|
||||
private static $course;
|
||||
private static $activity1context;
|
||||
private static $activity2context;
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::$syscontext = context_system::instance();
|
||||
self::$catcontext = context_coursecat::instance(1);
|
||||
self::$course = self::getDataGenerator()->create_course(array('category'=>1));
|
||||
self::$coursecontext = context_course::instance(self::$course->id);
|
||||
$page1 = self::getDataGenerator()->create_module('page', array('course'=>self::$course->id));
|
||||
self::$activity1context = context_module::instance($page1->cmid);
|
||||
$page2 = self::getDataGenerator()->create_module('page', array('course'=>self::$course->id));
|
||||
self::$activity2context = context_module::instance($page2->cmid);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
global $DB;
|
||||
parent::setUp();
|
||||
|
||||
$DB->delete_records('filter_active', array());
|
||||
$DB->delete_records('filter_config', array());
|
||||
$this->resetAfterTest(false);
|
||||
}
|
||||
|
||||
private function assert_matches($modinfo) {
|
||||
global $FILTERLIB_PRIVATE, $DB;
|
||||
|
||||
// Use preload cache...
|
||||
$FILTERLIB_PRIVATE = new stdClass();
|
||||
filter_preload_activities($modinfo);
|
||||
|
||||
// Get data and check no queries are made
|
||||
$before = $DB->perf_get_reads();
|
||||
$plfilters1 = filter_get_active_in_context(self::$activity1context);
|
||||
$plfilters2 = filter_get_active_in_context(self::$activity2context);
|
||||
$after = $DB->perf_get_reads();
|
||||
$this->assertEquals($before, $after);
|
||||
|
||||
// Repeat without cache and check it makes queries now
|
||||
$FILTERLIB_PRIVATE = new stdClass;
|
||||
$before = $DB->perf_get_reads();
|
||||
$filters1 = filter_get_active_in_context(self::$activity1context);
|
||||
$filters2 = filter_get_active_in_context(self::$activity2context);
|
||||
$after = $DB->perf_get_reads();
|
||||
$this->assertTrue($after > $before);
|
||||
|
||||
// Check they match
|
||||
$this->assertEquals($plfilters1, $filters1);
|
||||
$this->assertEquals($plfilters2, $filters2);
|
||||
}
|
||||
|
||||
public function test_preload() {
|
||||
// Get course and modinfo
|
||||
$modinfo = new course_modinfo(self::$course, 2);
|
||||
|
||||
// Note: All the tests in this function check that the result from the
|
||||
// preloaded cache is the same as the result from calling the standard
|
||||
// function without preloading.
|
||||
|
||||
// Initially, check with no filters enabled
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Enable filter globally, check
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Disable for activity 2
|
||||
filter_set_local_state('filter/name', self::$activity2context->id, TEXTFILTER_OFF);
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Disable at category
|
||||
filter_set_local_state('filter/name', self::$catcontext->id, TEXTFILTER_OFF);
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Enable for activity 1
|
||||
filter_set_local_state('filter/name', self::$activity1context->id, TEXTFILTER_ON);
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Disable globally
|
||||
filter_set_global_state('filter/name', TEXTFILTER_DISABLED);
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Add another 2 filters
|
||||
filter_set_global_state('filter/frog', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/zombie', TEXTFILTER_ON);
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Disable random one of these in each context
|
||||
filter_set_local_state('filter/zombie', self::$activity1context->id, TEXTFILTER_OFF);
|
||||
filter_set_local_state('filter/frog', self::$activity2context->id, TEXTFILTER_OFF);
|
||||
$this->assert_matches($modinfo);
|
||||
|
||||
// Now do some filter options
|
||||
filter_set_local_config('filter/name', self::$activity1context->id, 'a', 'x');
|
||||
filter_set_local_config('filter/zombie', self::$activity1context->id, 'a', 'y');
|
||||
filter_set_local_config('filter/frog', self::$activity1context->id, 'a', 'z');
|
||||
// These last two don't do anything as they are not at final level but I
|
||||
// thought it would be good to have that verified in test
|
||||
filter_set_local_config('filter/frog', self::$coursecontext->id, 'q', 'x');
|
||||
filter_set_local_config('filter/frog', self::$catcontext->id, 'q', 'z');
|
||||
$this->assert_matches($modinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class filter_delete_config_test extends advanced_testcase {
|
||||
public function setUp() {
|
||||
global $DB;
|
||||
parent::setUp();
|
||||
|
||||
$DB->delete_records('filter_active', array());
|
||||
$DB->delete_records('filter_config', array());
|
||||
$this->resetAfterTest(false);
|
||||
}
|
||||
|
||||
public function test_filter_delete_all_for_filter() {
|
||||
global $DB;
|
||||
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_global_state('filter/other', TEXTFILTER_ON);
|
||||
filter_set_local_config('filter/name', context_system::instance()->id, 'settingname', 'A value');
|
||||
filter_set_local_config('filter/other', context_system::instance()->id, 'settingname', 'Other value');
|
||||
set_config('configname', 'A config value', 'filter_name');
|
||||
set_config('configname', 'Other config value', 'filter_other');
|
||||
// Exercise SUT.
|
||||
filter_delete_all_for_filter('filter/name');
|
||||
// Validate.
|
||||
$this->assertEquals(1, $DB->count_records('filter_active'));
|
||||
$this->assertTrue($DB->record_exists('filter_active', array('filter' => 'filter/other')));
|
||||
$this->assertEquals(1, $DB->count_records('filter_config'));
|
||||
$this->assertTrue($DB->record_exists('filter_config', array('filter' => 'filter/other')));
|
||||
$expectedconfig = new stdClass;
|
||||
$expectedconfig->configname = 'Other config value';
|
||||
$this->assertEquals($expectedconfig, get_config('filter_other'));
|
||||
$this->assertEquals(get_config('filter_name'), new stdClass());
|
||||
}
|
||||
|
||||
public function test_filter_delete_all_for_context() {
|
||||
global $DB;
|
||||
|
||||
// Setup fixture.
|
||||
filter_set_global_state('filter/name', TEXTFILTER_ON);
|
||||
filter_set_local_state('filter/name', 123, TEXTFILTER_OFF);
|
||||
filter_set_local_config('filter/name', 123, 'settingname', 'A value');
|
||||
filter_set_local_config('filter/other', 123, 'settingname', 'Other value');
|
||||
filter_set_local_config('filter/other', 122, 'settingname', 'Other value');
|
||||
// Exercise SUT.
|
||||
filter_delete_all_for_context(123);
|
||||
// Validate.
|
||||
$this->assertEquals(1, $DB->count_records('filter_active'));
|
||||
$this->assertTrue($DB->record_exists('filter_active', array('contextid' => context_system::instance()->id)));
|
||||
$this->assertEquals(1, $DB->count_records('filter_config'));
|
||||
$this->assertTrue($DB->record_exists('filter_config', array('filter' => 'filter/other')));
|
||||
}
|
||||
}
|
||||
|
||||
class filter_filter_set_applies_to_strings extends advanced_testcase {
|
||||
protected $origcfgstringfilters;
|
||||
protected $origcfgfilterall;
|
||||
|
||||
public function setUp() {
|
||||
global $DB, $CFG;
|
||||
parent::setUp();
|
||||
|
||||
$DB->delete_records('filter_active', array());
|
||||
$DB->delete_records('filter_config', array());
|
||||
$this->resetAfterTest(false);
|
||||
|
||||
// Store original $CFG;
|
||||
$this->origcfgstringfilters = $CFG->stringfilters;
|
||||
$this->origcfgfilterall = $CFG->filterall;
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
global $CFG;
|
||||
$CFG->stringfilters = $this->origcfgstringfilters;
|
||||
$CFG->filterall = $this->origcfgfilterall;
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function test_set() {
|
||||
global $CFG;
|
||||
// Setup fixture.
|
||||
$CFG->filterall = 0;
|
||||
$CFG->stringfilters = '';
|
||||
// Exercise SUT.
|
||||
filter_set_applies_to_strings('filter/name', true);
|
||||
// Validate.
|
||||
$this->assertEquals('filter/name', $CFG->stringfilters);
|
||||
$this->assertEquals(1, $CFG->filterall);
|
||||
}
|
||||
|
||||
public function test_unset_to_empty() {
|
||||
global $CFG;
|
||||
// Setup fixture.
|
||||
$CFG->filterall = 1;
|
||||
$CFG->stringfilters = 'filter/name';
|
||||
// Exercise SUT.
|
||||
filter_set_applies_to_strings('filter/name', false);
|
||||
// Validate.
|
||||
$this->assertEquals('', $CFG->stringfilters);
|
||||
$this->assertEquals('', $CFG->filterall);
|
||||
}
|
||||
|
||||
public function test_unset_multi() {
|
||||
global $CFG;
|
||||
// Setup fixture.
|
||||
$CFG->filterall = 1;
|
||||
$CFG->stringfilters = 'filter/name,filter/other';
|
||||
// Exercise SUT.
|
||||
filter_set_applies_to_strings('filter/name', false);
|
||||
// Validate.
|
||||
$this->assertEquals('filter/other', $CFG->stringfilters);
|
||||
$this->assertEquals(1, $CFG->filterall);
|
||||
}
|
||||
}
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Test event handler definition used only from unit tests.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage event
|
||||
* @copyright 2007 onwards Martin Dougiamas (http://dougiamas.com)
|
||||
* @author Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$handlers = array (
|
||||
'test_instant' => array (
|
||||
'handlerfile' => '/lib/tests/eventslib_test.php',
|
||||
'handlerfunction' => 'sample_function_handler',
|
||||
'schedule' => 'instant',
|
||||
'internal' => 1,
|
||||
),
|
||||
|
||||
'test_cron' => array (
|
||||
'handlerfile' => '/lib/tests/eventslib_test.php',
|
||||
'handlerfunction' => array('sample_handler_class', 'static_method'),
|
||||
'schedule' => 'cron',
|
||||
'internal' => 1,
|
||||
)
|
||||
);
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for /lib/formslib.php.
|
||||
*
|
||||
* @package core_form
|
||||
* @category phpunit
|
||||
* @copyright 2011 Sam Hemelryk
|
||||
* @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');
|
||||
require_once($CFG->libdir . '/form/radio.php');
|
||||
require_once($CFG->libdir . '/form/select.php');
|
||||
require_once($CFG->libdir . '/form/text.php');
|
||||
|
||||
|
||||
class formslib_testcase extends basic_testcase {
|
||||
|
||||
public function test_require_rule() {
|
||||
global $CFG;
|
||||
|
||||
$strictformsrequired = null;
|
||||
if (isset($CFG->strictformsrequired)) {
|
||||
$strictformsrequired = $CFG->strictformsrequired;
|
||||
}
|
||||
|
||||
$rule = new MoodleQuickForm_Rule_Required();
|
||||
|
||||
// First run the tests with strictformsrequired off
|
||||
$CFG->strictformsrequired = false;
|
||||
// Passes
|
||||
$this->assertTrue($rule->validate('Something'));
|
||||
$this->assertTrue($rule->validate("Something\nmore"));
|
||||
$this->assertTrue($rule->validate("\nmore"));
|
||||
$this->assertTrue($rule->validate(" more "));
|
||||
$this->assertTrue($rule->validate("0"));
|
||||
$this->assertTrue($rule->validate(0));
|
||||
$this->assertTrue($rule->validate(true));
|
||||
$this->assertTrue($rule->validate(' '));
|
||||
$this->assertTrue($rule->validate(' '));
|
||||
$this->assertTrue($rule->validate("\t"));
|
||||
$this->assertTrue($rule->validate("\n"));
|
||||
$this->assertTrue($rule->validate("\r"));
|
||||
$this->assertTrue($rule->validate("\r\n"));
|
||||
$this->assertTrue($rule->validate(" \t \n \r "));
|
||||
$this->assertTrue($rule->validate('<p></p>'));
|
||||
$this->assertTrue($rule->validate('<p> </p>'));
|
||||
$this->assertTrue($rule->validate('<p>x</p>'));
|
||||
$this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile" />'));
|
||||
$this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"/>'));
|
||||
$this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"></img>'));
|
||||
$this->assertTrue($rule->validate('<hr />'));
|
||||
$this->assertTrue($rule->validate('<hr/>'));
|
||||
$this->assertTrue($rule->validate('<hr>'));
|
||||
$this->assertTrue($rule->validate('<hr></hr>'));
|
||||
$this->assertTrue($rule->validate('<br />'));
|
||||
$this->assertTrue($rule->validate('<br/>'));
|
||||
$this->assertTrue($rule->validate('<br>'));
|
||||
$this->assertTrue($rule->validate(' '));
|
||||
// Fails
|
||||
$this->assertFalse($rule->validate(''));
|
||||
$this->assertFalse($rule->validate(false));
|
||||
$this->assertFalse($rule->validate(null));
|
||||
|
||||
// Now run the same tests with it on to make sure things work as expected
|
||||
$CFG->strictformsrequired = true;
|
||||
// Passes
|
||||
$this->assertTrue($rule->validate('Something'));
|
||||
$this->assertTrue($rule->validate("Something\nmore"));
|
||||
$this->assertTrue($rule->validate("\nmore"));
|
||||
$this->assertTrue($rule->validate(" more "));
|
||||
$this->assertTrue($rule->validate("0"));
|
||||
$this->assertTrue($rule->validate(0));
|
||||
$this->assertTrue($rule->validate(true));
|
||||
$this->assertTrue($rule->validate('<p>x</p>'));
|
||||
$this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile" />'));
|
||||
$this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"/>'));
|
||||
$this->assertTrue($rule->validate('<img src="smile.jpg" alt="smile"></img>'));
|
||||
$this->assertTrue($rule->validate('<hr />'));
|
||||
$this->assertTrue($rule->validate('<hr/>'));
|
||||
$this->assertTrue($rule->validate('<hr>'));
|
||||
$this->assertTrue($rule->validate('<hr></hr>'));
|
||||
// Fails
|
||||
$this->assertFalse($rule->validate(' '));
|
||||
$this->assertFalse($rule->validate(' '));
|
||||
$this->assertFalse($rule->validate("\t"));
|
||||
$this->assertFalse($rule->validate("\n"));
|
||||
$this->assertFalse($rule->validate("\r"));
|
||||
$this->assertFalse($rule->validate("\r\n"));
|
||||
$this->assertFalse($rule->validate(" \t \n \r "));
|
||||
$this->assertFalse($rule->validate('<p></p>'));
|
||||
$this->assertFalse($rule->validate('<p> </p>'));
|
||||
$this->assertFalse($rule->validate('<br />'));
|
||||
$this->assertFalse($rule->validate('<br/>'));
|
||||
$this->assertFalse($rule->validate('<br>'));
|
||||
$this->assertFalse($rule->validate(' '));
|
||||
$this->assertFalse($rule->validate(''));
|
||||
$this->assertFalse($rule->validate(false));
|
||||
$this->assertFalse($rule->validate(null));
|
||||
|
||||
if (isset($strictformsrequired)) {
|
||||
$CFG->strictformsrequired = $strictformsrequired;
|
||||
}
|
||||
}
|
||||
|
||||
public function test_generate_id_select() {
|
||||
$el = new MoodleQuickForm_select('choose_one', 'Choose one',
|
||||
array(1 => 'One', '2' => 'Two'));
|
||||
$el->_generateId();
|
||||
$this->assertEquals('id_choose_one', $el->getAttribute('id'));
|
||||
}
|
||||
|
||||
public function test_generate_id_like_repeat() {
|
||||
$el = new MoodleQuickForm_text('text[7]', 'Type something');
|
||||
$el->_generateId();
|
||||
$this->assertEquals('id_text_7', $el->getAttribute('id'));
|
||||
}
|
||||
|
||||
public function test_can_manually_set_id() {
|
||||
$el = new MoodleQuickForm_text('elementname', 'Type something',
|
||||
array('id' => 'customelementid'));
|
||||
$el->_generateId();
|
||||
$this->assertEquals('customelementid', $el->getAttribute('id'));
|
||||
}
|
||||
|
||||
public function test_generate_id_radio() {
|
||||
$el = new MoodleQuickForm_radio('radio', 'Label', 'Choice label', 'choice_value');
|
||||
$el->_generateId();
|
||||
$this->assertEquals('id_radio_choice_value', $el->getAttribute('id'));
|
||||
}
|
||||
|
||||
public function test_radio_can_manually_set_id() {
|
||||
$el = new MoodleQuickForm_radio('radio2', 'Label', 'Choice label', 'choice_value',
|
||||
array('id' => 'customelementid2'));
|
||||
$el->_generateId();
|
||||
$this->assertEquals('customelementid2', $el->getAttribute('id'));
|
||||
}
|
||||
|
||||
public function test_generate_id_radio_like_repeat() {
|
||||
$el = new MoodleQuickForm_radio('repeatradio[2]', 'Label', 'Choice label', 'val');
|
||||
$el->_generateId();
|
||||
$this->assertEquals('id_repeatradio_2_val', $el->getAttribute('id'));
|
||||
}
|
||||
|
||||
public function test_rendering() {
|
||||
$form = new formslib_test_form();
|
||||
ob_start();
|
||||
$form->display();
|
||||
$html = ob_get_clean();
|
||||
|
||||
$this->assertTag(array('tag'=>'select', 'id'=>'id_choose_one',
|
||||
'attributes'=>array('name'=>'choose_one')), $html);
|
||||
|
||||
$this->assertTag(array('tag'=>'input', 'id'=>'id_text_0',
|
||||
'attributes'=>array('type'=>'text', 'name'=>'text[0]')), $html);
|
||||
|
||||
$this->assertTag(array('tag'=>'input', 'id'=>'id_text_1',
|
||||
'attributes'=>array('type'=>'text', 'name'=>'text[1]')), $html);
|
||||
|
||||
$this->assertTag(array('tag'=>'input', 'id'=>'id_radio_choice_value',
|
||||
'attributes'=>array('type'=>'radio', 'name'=>'radio', 'value'=>'choice_value')), $html);
|
||||
|
||||
$this->assertTag(array('tag'=>'input', 'id'=>'customelementid2',
|
||||
'attributes'=>array('type'=>'radio', 'name'=>'radio2')), $html);
|
||||
|
||||
$this->assertTag(array('tag'=>'input', 'id'=>'id_repeatradio_0_2',
|
||||
'attributes'=>array('type'=>'radio', 'name'=>'repeatradio[0]', 'value'=>'2')), $html);
|
||||
|
||||
$this->assertTag(array('tag'=>'input', 'id'=>'id_repeatradio_2_1',
|
||||
'attributes'=>array('type'=>'radio', 'name'=>'repeatradio[2]', 'value'=>'1')), $html);
|
||||
|
||||
$this->assertTag(array('tag'=>'input', 'id'=>'id_repeatradio_2_2',
|
||||
'attributes'=>array('type'=>'radio', 'name'=>'repeatradio[2]', 'value'=>'2')), $html);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test form to be used by {@link formslib_test::test_rendering()}.
|
||||
*/
|
||||
class formslib_test_form extends moodleform {
|
||||
public function definition() {
|
||||
$this->_form->addElement('select', 'choose_one', 'Choose one',
|
||||
array(1 => 'One', '2' => 'Two'));
|
||||
|
||||
$repeatels = array(
|
||||
$this->_form->createElement('text', 'text', 'Type something')
|
||||
);
|
||||
$this->repeat_elements($repeatels, 2, array(), 'numtexts', 'addtexts');
|
||||
|
||||
$this->_form->addElement('radio', 'radio', 'Label', 'Choice label', 'choice_value');
|
||||
|
||||
$this->_form->addElement('radio', 'radio2', 'Label', 'Choice label', 'choice_value',
|
||||
array('id' => 'customelementid2'));
|
||||
|
||||
$repeatels = array(
|
||||
$this->_form->createElement('radio', 'repeatradio', 'Choose {no}', 'One', 1),
|
||||
$this->_form->createElement('radio', 'repeatradio', 'Choose {no}', 'Two', 2),
|
||||
);
|
||||
$this->repeat_elements($repeatels, 3, array(), 'numradios', 'addradios');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?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 our html2text hacks
|
||||
*
|
||||
* Note: includes original tests from testweblib.php
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
class html2text_testcase extends basic_testcase {
|
||||
|
||||
/**
|
||||
* ALT as image replacements
|
||||
*/
|
||||
public function test_images() {
|
||||
$this->assertEquals('[edit]', html_to_text('<img src="edit.png" alt="edit" />'));
|
||||
|
||||
$text = 'xx<img src="gif.gif" alt="some gif" />xx';
|
||||
$result = html_to_text($text, null, false, false);
|
||||
$this->assertSame($result, 'xx[some gif]xx');
|
||||
}
|
||||
|
||||
/**
|
||||
* No magic quotes messing
|
||||
*/
|
||||
public function test_no_strip_slashes() {
|
||||
$this->assertEquals('[\edit]', html_to_text('<img src="edit.png" alt="\edit" />'));
|
||||
|
||||
$text = '\\magic\\quotes\\are\\\\horrible';
|
||||
$result = html_to_text($text, null, false, false);
|
||||
$this->assertSame($result, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Textlib integration
|
||||
*/
|
||||
public function test_textlib() {
|
||||
$text = '<strong>Žluťoučký koníček</strong>';
|
||||
$result = html_to_text($text, null, false, false);
|
||||
$this->assertSame($result, 'ŽLUŤOUČKÝ KONÍČEK');
|
||||
}
|
||||
|
||||
/**
|
||||
* Protect 0
|
||||
*/
|
||||
public function test_zero() {
|
||||
$text = '0';
|
||||
$result = html_to_text($text, null, false, false);
|
||||
$this->assertSame($result, $text);
|
||||
|
||||
$this->assertSame('0', html_to_text('0'));
|
||||
}
|
||||
|
||||
// ======= Standard html2text conversion features =======
|
||||
|
||||
/**
|
||||
* Various invalid HTML typed by users that ignore html strict
|
||||
**/
|
||||
public function test_invalid_html() {
|
||||
$text = 'Gin & Tonic';
|
||||
$result = html_to_text($text, null, false, false);
|
||||
$this->assertSame($result, $text);
|
||||
|
||||
$text = 'Gin > Tonic';
|
||||
$result = html_to_text($text, null, false, false);
|
||||
$this->assertSame($result, $text);
|
||||
|
||||
$text = 'Gin < Tonic';
|
||||
$result = html_to_text($text, null, false, false);
|
||||
$this->assertSame($result, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic text formatting.
|
||||
*/
|
||||
public function test_simple() {
|
||||
$this->assertEquals("_Hello_ WORLD!", html_to_text('<p><i>Hello</i> <b>world</b>!</p>'));
|
||||
$this->assertEquals("All the WORLD’S a stage.\n\n-- William Shakespeare", html_to_text('<p>All the <strong>world’s</strong> a stage.</p><p>-- William Shakespeare</p>'));
|
||||
$this->assertEquals("HELLO WORLD!\n\n", html_to_text('<h1>Hello world!</h1>'));
|
||||
$this->assertEquals("Hello\nworld!", html_to_text('Hello<br />world!'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test line wrapping
|
||||
*/
|
||||
public function test_text_nowrap() {
|
||||
$long = "Here is a long string, more than 75 characters long, since by default html_to_text wraps text at 75 chars.";
|
||||
$wrapped = "Here is a long string, more than 75 characters long, since by default\nhtml_to_text wraps text at 75 chars.";
|
||||
$this->assertEquals($long, html_to_text($long, 0));
|
||||
$this->assertEquals($wrapped, html_to_text($long));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whitespace removal
|
||||
*/
|
||||
public function test_trailing_whitespace() {
|
||||
$this->assertEquals('With trailing whitespace and some more text', html_to_text("With trailing whitespace \nand some more text", 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* PRE parsing
|
||||
*/
|
||||
public function test_html_to_text_pre_parsing_problem() {
|
||||
$strorig = 'Consider the following function:<br /><pre><span style="color: rgb(153, 51, 102);">void FillMeUp(char* in_string) {'.
|
||||
'<br /> int i = 0;<br /> while (in_string[i] != \'\0\') {<br /> in_string[i] = \'X\';<br /> i++;<br /> }<br />'.
|
||||
'}</span></pre>What would happen if a non-terminated string were input to this function?<br /><br />';
|
||||
|
||||
$strconv = 'Consider the following function:
|
||||
|
||||
void FillMeUp(char* in_string) {
|
||||
int i = 0;
|
||||
while (in_string[i] != \'\0\') {
|
||||
in_string[i] = \'X\';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
What would happen if a non-terminated string were input to this function?
|
||||
|
||||
';
|
||||
|
||||
$this->assertSame($strconv, html_to_text($strorig));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?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/>.
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for the html_writer class.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2010 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/outputcomponents.php');
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for the html_writer class.
|
||||
*
|
||||
* @copyright 2010 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class html_writer_testcase extends basic_testcase {
|
||||
|
||||
public function test_start_tag() {
|
||||
$this->assertEquals('<div>', html_writer::start_tag('div'));
|
||||
}
|
||||
|
||||
public function test_start_tag_with_attr() {
|
||||
$this->assertEquals('<div class="frog">',
|
||||
html_writer::start_tag('div', array('class' => 'frog')));
|
||||
}
|
||||
|
||||
public function test_start_tag_with_attrs() {
|
||||
$this->assertEquals('<div class="frog" id="mydiv">',
|
||||
html_writer::start_tag('div', array('class' => 'frog', 'id' => 'mydiv')));
|
||||
}
|
||||
|
||||
public function test_end_tag() {
|
||||
$this->assertEquals('</div>', html_writer::end_tag('div'));
|
||||
}
|
||||
|
||||
public function test_empty_tag() {
|
||||
$this->assertEquals('<br />', html_writer::empty_tag('br'));
|
||||
}
|
||||
|
||||
public function test_empty_tag_with_attrs() {
|
||||
$this->assertEquals('<input type="submit" value="frog" />',
|
||||
html_writer::empty_tag('input', array('type' => 'submit', 'value' => 'frog')));
|
||||
}
|
||||
|
||||
public function test_nonempty_tag_with_content() {
|
||||
$this->assertEquals('<div>Hello world!</div>',
|
||||
html_writer::nonempty_tag('div', 'Hello world!'));
|
||||
}
|
||||
|
||||
public function test_nonempty_tag_empty() {
|
||||
$this->assertEquals('',
|
||||
html_writer::nonempty_tag('div', ''));
|
||||
}
|
||||
|
||||
public function test_nonempty_tag_null() {
|
||||
$this->assertEquals('',
|
||||
html_writer::nonempty_tag('div', null));
|
||||
}
|
||||
|
||||
public function test_nonempty_tag_zero() {
|
||||
$this->assertEquals('<div class="score">0</div>',
|
||||
html_writer::nonempty_tag('div', 0, array('class' => 'score')));
|
||||
}
|
||||
|
||||
public function test_nonempty_tag_zero_string() {
|
||||
$this->assertEquals('<div class="score">0</div>',
|
||||
html_writer::nonempty_tag('div', '0', array('class' => 'score')));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests of mathslib wrapper and underlying EvalMath library.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2007 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/mathslib.php');
|
||||
|
||||
|
||||
class mathsslib_testcase extends basic_testcase {
|
||||
|
||||
/**
|
||||
* Tests the basic formula evaluation
|
||||
*/
|
||||
public function test__basic() {
|
||||
$formula = new calc_formula('=1+2');
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 3, '3+1 is: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the formula params
|
||||
*/
|
||||
public function test__params() {
|
||||
$formula = new calc_formula('=a+b+c', array('a'=>10, 'b'=>20, 'c'=>30));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 60, '10+20+30 is: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the changed params
|
||||
*/
|
||||
public function test__changing_params() {
|
||||
$formula = new calc_formula('=a+b+c', array('a'=>10, 'b'=>20, 'c'=>30));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 60, '10+20+30 is: %s');
|
||||
$formula->set_params(array('a'=>1, 'b'=>2, 'c'=>3));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 6, 'changed params 1+2+3 is: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the spreadsheet emulation function in formula
|
||||
*/
|
||||
public function test__calc_function() {
|
||||
$formula = new calc_formula('=sum(a, b, c)', array('a'=>10, 'b'=>20, 'c'=>30));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 60, 'sum(a, b, c) is: %s');
|
||||
}
|
||||
|
||||
public function test_other_functions() {
|
||||
$formula = new calc_formula('=average(1,2,3)');
|
||||
$this->assertEquals($formula->evaluate(), 2);
|
||||
|
||||
$formula = new calc_formula('=mod(10,3)');
|
||||
$this->assertEquals($formula->evaluate(), 1);
|
||||
|
||||
$formula = new calc_formula('=power(2,3)');
|
||||
$this->assertEquals($formula->evaluate(), 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the min and max functions
|
||||
*/
|
||||
public function test__minmax_function() {
|
||||
$formula = new calc_formula('=min(a, b, c)', array('a'=>10, 'b'=>20, 'c'=>30));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 10, 'minimum is: %s');
|
||||
$formula = new calc_formula('=max(a, b, c)', array('a'=>10, 'b'=>20, 'c'=>30));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 30, 'maximum is: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests special chars
|
||||
*/
|
||||
public function test__specialchars() {
|
||||
$formula = new calc_formula('=gi1 + gi2 + gi11', array('gi1'=>10, 'gi2'=>20, 'gi11'=>30));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, 60, 'sum is: %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests some slightly more complex expressions
|
||||
*/
|
||||
public function test__more_complex_expressions() {
|
||||
$formula = new calc_formula('=pi() + a', array('a'=>10));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, pi()+10);
|
||||
$formula = new calc_formula('=pi()^a', array('a'=>10));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, pow(pi(), 10));
|
||||
$formula = new calc_formula('=-8*(5/2)^2*(1-sqrt(4))-8');
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, -8*pow((5/2), 2)*(1-sqrt(4))-8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests some slightly more complex expressions
|
||||
*/
|
||||
public function test__error_handling() {
|
||||
$formula = new calc_formula('=pi( + a', array('a'=>10));
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, false);
|
||||
$this->assertEquals($formula->get_error(),
|
||||
get_string('unexpectedoperator', 'mathslib', '+'));
|
||||
|
||||
$formula = new calc_formula('=pi(');
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, false);
|
||||
$this->assertEquals($formula->get_error(),
|
||||
get_string('expectingaclosingbracket', 'mathslib'));
|
||||
|
||||
$formula = new calc_formula('=pi()^');
|
||||
$res = $formula->evaluate();
|
||||
$this->assertEquals($res, false);
|
||||
$this->assertEquals($formula->get_error(),
|
||||
get_string('operatorlacksoperand', 'mathslib', '^'));
|
||||
|
||||
}
|
||||
|
||||
public function test_rounding_function() {
|
||||
$formula = new calc_formula('=round(2.5)');
|
||||
$this->assertEquals($formula->evaluate(), 3);
|
||||
|
||||
$formula = new calc_formula('=round(1.5)');
|
||||
$this->assertEquals($formula->evaluate(), 2);
|
||||
|
||||
$formula = new calc_formula('=round(-1.49)');
|
||||
$this->assertEquals($formula->evaluate(), -1);
|
||||
|
||||
$formula = new calc_formula('=round(-2.49)');
|
||||
$this->assertEquals($formula->evaluate(), -2);
|
||||
|
||||
$formula = new calc_formula('=round(-1.5)');
|
||||
$this->assertEquals($formula->evaluate(), -2);
|
||||
|
||||
$formula = new calc_formula('=round(-2.5)');
|
||||
$this->assertEquals($formula->evaluate(), -3);
|
||||
|
||||
$formula = new calc_formula('=ceil(2.5)');
|
||||
$this->assertEquals($formula->evaluate(), 3);
|
||||
|
||||
$formula = new calc_formula('=ceil(1.5)');
|
||||
$this->assertEquals($formula->evaluate(), 2);
|
||||
|
||||
$formula = new calc_formula('=ceil(-1.49)');
|
||||
$this->assertEquals($formula->evaluate(), -1);
|
||||
|
||||
$formula = new calc_formula('=ceil(-2.49)');
|
||||
$this->assertEquals($formula->evaluate(), -2);
|
||||
|
||||
$formula = new calc_formula('=ceil(-1.5)');
|
||||
$this->assertEquals($formula->evaluate(), -1);
|
||||
|
||||
$formula = new calc_formula('=ceil(-2.5)');
|
||||
$this->assertEquals($formula->evaluate(), -2);
|
||||
|
||||
$formula = new calc_formula('=floor(2.5)');
|
||||
$this->assertEquals($formula->evaluate(), 2);
|
||||
|
||||
$formula = new calc_formula('=floor(1.5)');
|
||||
$this->assertEquals($formula->evaluate(), 1);
|
||||
|
||||
$formula = new calc_formula('=floor(-1.49)');
|
||||
$this->assertEquals($formula->evaluate(), -2);
|
||||
|
||||
$formula = new calc_formula('=floor(-2.49)');
|
||||
$this->assertEquals($formula->evaluate(), -3);
|
||||
|
||||
$formula = new calc_formula('=floor(-1.5)');
|
||||
$this->assertEquals($formula->evaluate(), -2);
|
||||
|
||||
$formula = new calc_formula('=floor(-2.5)');
|
||||
$this->assertEquals($formula->evaluate(), -3);
|
||||
|
||||
}
|
||||
|
||||
public function test_scientific_notation() {
|
||||
$formula = new calc_formula('=10e10');
|
||||
$this->assertEquals($formula->evaluate(), 1e11, '', 1e11*1e-15);
|
||||
|
||||
$formula = new calc_formula('=10e-10');
|
||||
$this->assertEquals($formula->evaluate(), 1e-9, '', 1e11*1e-15);
|
||||
|
||||
$formula = new calc_formula('=10e+10');
|
||||
$this->assertEquals($formula->evaluate(), 1e11, '', 1e11*1e-15);
|
||||
|
||||
$formula = new calc_formula('=10e10*5');
|
||||
$this->assertEquals($formula->evaluate(), 5e11, '', 1e11*1e-15);
|
||||
|
||||
$formula = new calc_formula('=10e10^2');
|
||||
$this->assertEquals($formula->evaluate(), 1e22, '', 1e22*1e-15);
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,232 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for lib/outputcomponents.php.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2011 David Mudrak <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/outputcomponents.php');
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for the user_picture class
|
||||
*/
|
||||
class user_picture_testcase extends basic_testcase {
|
||||
|
||||
public function test_user_picture_fields_aliasing() {
|
||||
$fields = user_picture::fields();
|
||||
$fields = array_map('trim', explode(',', $fields));
|
||||
$this->assertTrue(in_array('id', $fields));
|
||||
|
||||
$aliased = array();
|
||||
foreach ($fields as $field) {
|
||||
if ($field === 'id') {
|
||||
$aliased['id'] = 'aliasedid';
|
||||
} else {
|
||||
$aliased[$field] = 'prefix'.$field;
|
||||
}
|
||||
}
|
||||
|
||||
$returned = user_picture::fields('', array('custom1', 'id'), 'aliasedid', 'prefix');
|
||||
$returned = array_map('trim', explode(',', $returned));
|
||||
$this->assertEquals(count($returned), count($fields) + 1); // only one extra field added
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if ($field === 'id') {
|
||||
$expected = "id AS aliasedid";
|
||||
} else {
|
||||
$expected = "$field AS prefix$field";
|
||||
}
|
||||
$this->assertTrue(in_array($expected, $returned), "Expected pattern '$expected' not returned");
|
||||
}
|
||||
$this->assertTrue(in_array("custom1 AS prefixcustom1", $returned), "Expected pattern 'custom1 AS prefixcustom1' not returned");
|
||||
}
|
||||
|
||||
public function test_user_picture_fields_unaliasing() {
|
||||
$fields = user_picture::fields();
|
||||
$fields = array_map('trim', explode(',', $fields));
|
||||
|
||||
$fakerecord = new stdClass();
|
||||
$fakerecord->aliasedid = 42;
|
||||
foreach ($fields as $field) {
|
||||
if ($field !== 'id') {
|
||||
$fakerecord->{'prefix'.$field} = "Value of $field";
|
||||
}
|
||||
}
|
||||
$fakerecord->prefixcustom1 = 'Value of custom1';
|
||||
|
||||
$returned = user_picture::unalias($fakerecord, array('custom1'), 'aliasedid', 'prefix');
|
||||
|
||||
$this->assertEquals($returned->id, 42);
|
||||
foreach ($fields as $field) {
|
||||
if ($field !== 'id') {
|
||||
$this->assertEquals($returned->{$field}, "Value of $field");
|
||||
}
|
||||
}
|
||||
$this->assertEquals($returned->custom1, 'Value of custom1');
|
||||
}
|
||||
|
||||
public function test_user_picture_fields_unaliasing_null() {
|
||||
$fields = user_picture::fields();
|
||||
$fields = array_map('trim', explode(',', $fields));
|
||||
|
||||
$fakerecord = new stdClass();
|
||||
$fakerecord->aliasedid = 42;
|
||||
foreach ($fields as $field) {
|
||||
if ($field !== 'id') {
|
||||
$fakerecord->{'prefix'.$field} = "Value of $field";
|
||||
}
|
||||
}
|
||||
$fakerecord->prefixcustom1 = 'Value of custom1';
|
||||
$fakerecord->prefiximagealt = null;
|
||||
|
||||
$returned = user_picture::unalias($fakerecord, array('custom1'), 'aliasedid', 'prefix');
|
||||
|
||||
$this->assertEquals($returned->id, 42);
|
||||
$this->assertEquals($returned->imagealt, null);
|
||||
foreach ($fields as $field) {
|
||||
if ($field !== 'id' and $field !== 'imagealt') {
|
||||
$this->assertEquals($returned->{$field}, "Value of $field");
|
||||
}
|
||||
}
|
||||
$this->assertEquals($returned->custom1, 'Value of custom1');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for the custom_menu class
|
||||
*/
|
||||
class custom_menu_testcase extends basic_testcase {
|
||||
|
||||
public function test_empty_menu() {
|
||||
$emptymenu = new custom_menu();
|
||||
$this->assertTrue($emptymenu instanceof custom_menu);
|
||||
$this->assertFalse($emptymenu->has_children());
|
||||
}
|
||||
|
||||
public function test_basic_syntax() {
|
||||
$definition = <<<EOF
|
||||
Moodle community|http://moodle.org
|
||||
-Moodle free support|http://moodle.org/support
|
||||
-Moodle development|http://moodle.org/development
|
||||
--Moodle Tracker|http://tracker.moodle.org
|
||||
--Moodle Docs|http://docs.moodle.org
|
||||
-Moodle News|http://moodle.org/news
|
||||
Moodle company
|
||||
-Hosting|http://moodle.com/hosting|Commercial hosting
|
||||
-Support|http://moodle.com/support|Commercial support
|
||||
EOF;
|
||||
|
||||
$menu = new custom_menu($definition);
|
||||
$this->assertTrue($menu instanceof custom_menu);
|
||||
$this->assertTrue($menu->has_children());
|
||||
$firstlevel = $menu->get_children();
|
||||
$this->assertTrue(is_array($firstlevel));
|
||||
$this->assertEquals(2, count($firstlevel));
|
||||
|
||||
$item = array_shift($firstlevel);
|
||||
$this->assertTrue($item instanceof custom_menu_item);
|
||||
$this->assertTrue($item->has_children());
|
||||
$this->assertEquals(3, count($item->get_children()));
|
||||
$this->assertEquals('Moodle community', $item->get_text());
|
||||
$itemurl = $item->get_url();
|
||||
$this->assertTrue($itemurl instanceof moodle_url);
|
||||
$this->assertEquals('http://moodle.org', $itemurl->out());
|
||||
$this->assertEquals($item->get_text(), $item->get_title()); // implicit title
|
||||
|
||||
$item = array_shift($firstlevel);
|
||||
$this->assertTrue($item->has_children());
|
||||
$this->assertEquals(2, count($item->get_children()));
|
||||
$this->assertEquals('Moodle company', $item->get_text());
|
||||
$this->assertTrue(is_null($item->get_url()));
|
||||
|
||||
$children = $item->get_children();
|
||||
$subitem = array_shift($children);
|
||||
$this->assertFalse($subitem->has_children());
|
||||
$this->assertEquals('Hosting', $subitem->get_text());
|
||||
$this->assertEquals('Commercial hosting', $subitem->get_title());
|
||||
}
|
||||
|
||||
public function test_multilang_support() {
|
||||
$definition = <<<EOF
|
||||
Start|http://school.info
|
||||
Info
|
||||
-English|http://school.info/en|Information in English|en
|
||||
-Deutsch|http://school.info/de|Informationen in deutscher Sprache|de,de_du,de_kids
|
||||
EOF;
|
||||
|
||||
// the menu without multilang support
|
||||
$menu = new custom_menu($definition);
|
||||
$this->assertTrue($menu->has_children());
|
||||
$this->assertEquals(2, count($menu->get_children()));
|
||||
|
||||
$children = $menu->get_children();
|
||||
$infomenu = array_pop($children);
|
||||
$this->assertTrue($infomenu->has_children());
|
||||
$children = $infomenu->get_children();
|
||||
$this->assertEquals(2, count($children));
|
||||
|
||||
$children = $infomenu->get_children();
|
||||
$langspecinfo = array_shift($children);
|
||||
$this->assertEquals('Information in English', $langspecinfo->get_title());
|
||||
|
||||
// same menu for English language selected
|
||||
$menu = new custom_menu($definition, 'en');
|
||||
$this->assertTrue($menu->has_children());
|
||||
$this->assertEquals(2, count($menu->get_children()));
|
||||
|
||||
$children = $menu->get_children();
|
||||
$infomenu = array_pop($children);
|
||||
$this->assertTrue($infomenu->has_children());
|
||||
$this->assertEquals(1, count($infomenu->get_children()));
|
||||
|
||||
$children = $infomenu->get_children();
|
||||
$langspecinfo = array_shift($children);
|
||||
$this->assertEquals('Information in English', $langspecinfo->get_title());
|
||||
|
||||
// same menu for German (de_du) language selected
|
||||
$menu = new custom_menu($definition, 'de_du');
|
||||
$this->assertTrue($menu->has_children());
|
||||
$this->assertEquals(2, count($menu->get_children()));
|
||||
|
||||
$children = $menu->get_children();
|
||||
$infomenu = array_pop($children);
|
||||
$this->assertTrue($infomenu->has_children());
|
||||
$this->assertEquals(1, count($infomenu->get_children()));
|
||||
|
||||
$children = $infomenu->get_children();
|
||||
$langspecinfo = array_shift($children);
|
||||
$this->assertEquals('Informationen in deutscher Sprache', $langspecinfo->get_title());
|
||||
|
||||
// same menu for Czech language selected
|
||||
$menu = new custom_menu($definition, 'cs');
|
||||
$this->assertTrue($menu->has_children());
|
||||
$this->assertEquals(2, count($menu->get_children()));
|
||||
|
||||
$children = $infomenu->get_children();
|
||||
$infomenu = array_pop( $children);
|
||||
$this->assertFalse($infomenu->has_children());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for (some of) ../outputlib.php.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later (5)
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/outputlib.php');
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for the xhtml_container_stack class.
|
||||
*
|
||||
* These tests assume that developer debug mode is on, which, at the time of
|
||||
* writing, is true. admin/tool/unittest/index.php forces it on.
|
||||
*
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class xhtml_container_stack_testcase extends basic_testcase {
|
||||
protected function start_capture() {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
protected function end_capture() {
|
||||
$result = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function test_push_then_pop() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$stack->push('testtype', '</div>');
|
||||
$html = $stack->pop('testtype');
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('</div>', $html);
|
||||
$this->assertEquals('', $errors);
|
||||
}
|
||||
|
||||
public function test_mismatched_pop_prints_warning() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
$stack->push('testtype', '</div>');
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$html = $stack->pop('mismatch');
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('</div>', $html);
|
||||
$this->assertNotEquals('', $errors);
|
||||
}
|
||||
|
||||
public function test_pop_when_empty_prints_warning() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$html = $stack->pop('testtype');
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('', $html);
|
||||
$this->assertNotEquals('', $errors);
|
||||
}
|
||||
|
||||
public function test_correct_nesting() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$stack->push('testdiv', '</div>');
|
||||
$stack->push('testp', '</p>');
|
||||
$html2 = $stack->pop('testp');
|
||||
$html1 = $stack->pop('testdiv');
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('</p>', $html2);
|
||||
$this->assertEquals('</div>', $html1);
|
||||
$this->assertEquals('', $errors);
|
||||
}
|
||||
|
||||
public function test_pop_all_but_last() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
$stack->push('test1', '</h1>');
|
||||
$stack->push('test2', '</h2>');
|
||||
$stack->push('test3', '</h3>');
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$html = $stack->pop_all_but_last();
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('</h3></h2>', $html);
|
||||
$this->assertEquals('', $errors);
|
||||
// Tear down.
|
||||
$stack->discard();
|
||||
}
|
||||
|
||||
public function test_pop_all_but_last_only_one() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
$stack->push('test1', '</h1>');
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$html = $stack->pop_all_but_last();
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('', $html);
|
||||
$this->assertEquals('', $errors);
|
||||
// Tear down.
|
||||
$stack->discard();
|
||||
}
|
||||
|
||||
public function test_pop_all_but_last_empty() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$html = $stack->pop_all_but_last();
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('', $html);
|
||||
$this->assertEquals('', $errors);
|
||||
}
|
||||
|
||||
public function test_discard() {
|
||||
// Set up.
|
||||
$stack = new xhtml_container_stack();
|
||||
$stack->push('test1', '</somethingdistinctive>');
|
||||
$stack->discard();
|
||||
// Exercise SUT.
|
||||
$this->start_capture();
|
||||
$stack = null;
|
||||
$errors = $this->end_capture();
|
||||
// Verify outcome
|
||||
$this->assertEquals('', $errors);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for (some of) ../questionlib.php.
|
||||
*
|
||||
* @package core_question
|
||||
* @category phpunit
|
||||
* @copyright 2006 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for (some of) ../questionlib.php.
|
||||
*
|
||||
* @copyright 2006 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class questionlib_testcase extends basic_testcase {
|
||||
|
||||
public function test_question_reorder_qtypes() {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
|
||||
$this->assertEquals(question_reorder_qtypes(
|
||||
array('t1' => '', 't2' => '', 't3' => ''), 't1', +1),
|
||||
array(0 => 't2', 1 => 't1', 2 => 't3'));
|
||||
$this->assertEquals(question_reorder_qtypes(
|
||||
array('t1' => '', 't2' => '', 't3' => ''), 't1', -1),
|
||||
array(0 => 't1', 1 => 't2', 2 => 't3'));
|
||||
$this->assertEquals(question_reorder_qtypes(
|
||||
array('t1' => '', 't2' => '', 't3' => ''), 't2', -1),
|
||||
array(0 => 't2', 1 => 't1', 2 => 't3'));
|
||||
$this->assertEquals(question_reorder_qtypes(
|
||||
array('t1' => '', 't2' => '', 't3' => ''), 't3', +1),
|
||||
array(0 => 't1', 1 => 't2', 2 => 't3'));
|
||||
$this->assertEquals(question_reorder_qtypes(
|
||||
array('t1' => '', 't2' => '', 't3' => ''), 'missing', +1),
|
||||
array(0 => 't1', 1 => 't2', 2 => 't3'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* These tests rely on the rsstest.xml file on download.moodle.org,
|
||||
* from eloys listing:
|
||||
* rsstest.xml: One valid rss feed.
|
||||
* md5: 8fd047914863bf9b3a4b1514ec51c32c
|
||||
* size: 32188
|
||||
*
|
||||
* If networking/proxy configuration is wrong these tests will fail..
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2009 Dan Poltawski
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir.'/simplepie/moodle_simplepie.php');
|
||||
|
||||
|
||||
class moodlesimplepie_testcase extends basic_testcase {
|
||||
|
||||
# A url we know exists and is valid
|
||||
const VALIDURL = 'http://download.moodle.org/unittest/rsstest.xml';
|
||||
# A url which we know doesn't exist
|
||||
const INVALIDURL = 'http://download.moodle.org/unittest/rsstest-which-doesnt-exist.xml';
|
||||
# This tinyurl redirects to th rsstest.xml file
|
||||
const REDIRECTURL = 'http://tinyurl.com/lvyslv';
|
||||
|
||||
function setUp() {
|
||||
moodle_simplepie::reset_cache();
|
||||
}
|
||||
|
||||
function test_getfeed() {
|
||||
$feed = new moodle_simplepie(self::VALIDURL);
|
||||
|
||||
$this->assertInstanceOf('moodle_simplepie', $feed);
|
||||
|
||||
$this->assertNull($feed->error(), "Failed to load the sample RSS file. Please check your proxy settings in Moodle. %s");
|
||||
if ($feed->error()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals($feed->get_title(), 'Moodle News');
|
||||
|
||||
$this->assertEquals($feed->get_link(), 'http://moodle.org/mod/forum/view.php?f=1');
|
||||
$this->assertEquals($feed->get_description(), "General news about Moodle.\n\nMoodle is a leading open-source course management system (CMS) - a software package designed to help educators create quality online courses. Such e-learning systems are sometimes also called Learning Management Systems (LMS) or Virtual Learning Environments (VLE). One of the main advantages of Moodle over other systems is a strong grounding in social constructionist pedagogy.");
|
||||
|
||||
$this->assertEquals($feed->get_copyright(), '&#169; 2007 moodle');
|
||||
$this->assertEquals($feed->get_image_url(), 'http://moodle.org/pix/i/rsssitelogo.gif');
|
||||
$this->assertEquals($feed->get_image_title(), 'moodle');
|
||||
$this->assertEquals($feed->get_image_link(), 'http://moodle.org');
|
||||
$this->assertEquals($feed->get_image_width(), '140');
|
||||
$this->assertEquals($feed->get_image_height(), '35');
|
||||
|
||||
$this->assertNotEmpty($items = $feed->get_items());
|
||||
$this->assertEquals(count($items), 15);
|
||||
|
||||
$this->assertNotEmpty($itemone = $feed->get_item(0));
|
||||
if (!$itemone) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals($itemone->get_title(), 'Google HOP contest encourages pre-University students to work on Moodle');
|
||||
$this->assertEquals($itemone->get_link(), 'http://moodle.org/mod/forum/discuss.php?d=85629');
|
||||
$this->assertEquals($itemone->get_id(), 'http://moodle.org/mod/forum/discuss.php?d=85629');
|
||||
$description = <<<EOD
|
||||
by Martin Dougiamas. <p><p><img src="http://code.google.com/opensource/ghop/2007-8/images/ghoplogosm.jpg" align="right" style="margin:10px" />After their very successful <a href="http://code.google.com/soc/2007/">Summer of Code</a> program for University students, Google just announced their new <a href="http://code.google.com/opensource/ghop/2007-8/">Highly Open Participation contest</a>, designed to encourage pre-University students to get involved with open source projects via much smaller and diverse contributions.<br />
|
||||
<br />
|
||||
I'm very proud that Moodle has been selected as one of only <a href="http://code.google.com/opensource/ghop/2007-8/projects.html">ten open source projects</a> to take part in the inaugural year of this new contest.<br />
|
||||
<br />
|
||||
We have a <a href="http://code.google.com/p/google-highly-open-participation-moodle/issues/list">long list of small tasks</a> prepared already for students, but we would definitely like to see the Moodle community come up with more - so if you have any ideas for things you want to see done, please <a href="http://code.google.com/p/google-highly-open-participation-moodle/">send them to us</a>! Just remember they can't take more than five days.<br />
|
||||
<br />
|
||||
Google will pay students US$100 for every three tasks they successfully complete, plus send a cool T-shirt. There are also grand prizes including an all-expenses-paid trip to Google HQ in Mountain View, California. If you are (or know) a young student with an interest in Moodle then give it a go! <br />
|
||||
<br />
|
||||
You can find out all the details on the <a href="http://code.google.com/p/google-highly-open-participation-moodle/">Moodle/GHOP contest site</a>.</p></p>
|
||||
EOD;
|
||||
$this->assertEquals($itemone->get_description(), $description);
|
||||
|
||||
|
||||
// TODO fix this so it uses $CFG by default
|
||||
$this->assertEquals($itemone->get_date('U'), 1196412453);
|
||||
|
||||
// last item
|
||||
$this->assertNotEmpty($feed->get_item(14));
|
||||
// Past last item
|
||||
$this->assertEmpty($feed->get_item(15));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test retrieving a url which doesn't exist
|
||||
*/
|
||||
function test_failurl() {
|
||||
$feed = @new moodle_simplepie(self::INVALIDURL); // we do not want this in php error log
|
||||
|
||||
$this->assertNotEmpty($feed->error());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test retrieving a url with broken proxy configuration
|
||||
*/
|
||||
function test_failproxy() {
|
||||
global $CFG;
|
||||
|
||||
$oldproxy = $CFG->proxyhost;
|
||||
$CFG->proxyhost = 'xxxxxxxxxxxxxxx.moodle.org';
|
||||
|
||||
$feed = new moodle_simplepie(self::VALIDURL);
|
||||
|
||||
$this->assertNotEmpty($feed->error());
|
||||
$this->assertEmpty($feed->get_title());
|
||||
$CFG->proxyhost = $oldproxy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test retrieving a url which sends a redirect to another valid feed
|
||||
*/
|
||||
function test_redirect() {
|
||||
global $CFG;
|
||||
|
||||
$feed = new moodle_simplepie(self::REDIRECTURL);
|
||||
|
||||
$this->assertNull($feed->error());
|
||||
$this->assertEquals($feed->get_title(), 'Moodle News');
|
||||
$this->assertEquals($feed->get_link(), 'http://moodle.org/mod/forum/view.php?f=1');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* These tests rely on the rsstest.xml file on download.moodle.org,
|
||||
* from eloys listing:
|
||||
* rsstest.xml: One valid rss feed.
|
||||
* md5: 8fd047914863bf9b3a4b1514ec51c32c
|
||||
* size: 32188
|
||||
*
|
||||
* If networking/proxy configuration is wrong these tests will fail..
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright © 2006 The Open University
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
class web_testcase extends basic_testcase {
|
||||
|
||||
function test_format_string() {
|
||||
global $CFG;
|
||||
|
||||
// Ampersands
|
||||
$this->assertEquals(format_string("& &&&&& &&"), "& &&&&& &&");
|
||||
$this->assertEquals(format_string("ANother & &&&&& Category"), "ANother & &&&&& Category");
|
||||
$this->assertEquals(format_string("ANother & &&&&& Category", true), "ANother & &&&&& Category");
|
||||
$this->assertEquals(format_string("Nick's Test Site & Other things", true), "Nick's Test Site & Other things");
|
||||
|
||||
// String entities
|
||||
$this->assertEquals(format_string("""), """);
|
||||
|
||||
// Digital entities
|
||||
$this->assertEquals(format_string("&11234;"), "&11234;");
|
||||
|
||||
// Unicode entities
|
||||
$this->assertEquals(format_string("ᅻ"), "ᅻ");
|
||||
|
||||
// < and > signs
|
||||
$originalformatstringstriptags = $CFG->formatstringstriptags;
|
||||
|
||||
$CFG->formatstringstriptags = false;
|
||||
$this->assertEquals(format_string('x < 1'), 'x < 1');
|
||||
$this->assertEquals(format_string('x > 1'), 'x > 1');
|
||||
$this->assertEquals(format_string('x < 1 and x > 0'), 'x < 1 and x > 0');
|
||||
|
||||
$CFG->formatstringstriptags = true;
|
||||
$this->assertEquals(format_string('x < 1'), 'x < 1');
|
||||
$this->assertEquals(format_string('x > 1'), 'x > 1');
|
||||
$this->assertEquals(format_string('x < 1 and x > 0'), 'x < 1 and x > 0');
|
||||
|
||||
$CFG->formatstringstriptags = $originalformatstringstriptags;
|
||||
}
|
||||
|
||||
function test_s() {
|
||||
$this->assertEquals(s("This Breaks \" Strict"), "This Breaks " Strict");
|
||||
$this->assertEquals(s("This Breaks <a>\" Strict</a>"), "This Breaks <a>" Strict</a>");
|
||||
}
|
||||
|
||||
function test_format_text_email() {
|
||||
$this->assertEquals("This is a TEST",
|
||||
format_text_email('<p>This is a <strong>test</strong></p>',FORMAT_HTML));
|
||||
$this->assertEquals("This is a TEST",
|
||||
format_text_email('<p class="frogs">This is a <strong class=\'fishes\'>test</strong></p>',FORMAT_HTML));
|
||||
$this->assertEquals('& so is this',
|
||||
format_text_email('& so is this',FORMAT_HTML));
|
||||
$this->assertEquals('Two bullets: '.textlib::code2utf8(8226).' *',
|
||||
format_text_email('Two bullets: • •',FORMAT_HTML));
|
||||
$this->assertEquals(textlib::code2utf8(0x7fd2).textlib::code2utf8(0x7fd2),
|
||||
format_text_email('習習',FORMAT_HTML));
|
||||
}
|
||||
|
||||
function test_highlight() {
|
||||
$this->assertEquals(highlight('good', 'This is good'), 'This is <span class="highlight">good</span>');
|
||||
$this->assertEquals(highlight('SpaN', 'span'), '<span class="highlight">span</span>');
|
||||
$this->assertEquals(highlight('span', 'SpaN'), '<span class="highlight">SpaN</span>');
|
||||
$this->assertEquals(highlight('span', '<span>span</span>'), '<span><span class="highlight">span</span></span>');
|
||||
$this->assertEquals(highlight('good is', 'He is good'), 'He <span class="highlight">is</span> <span class="highlight">good</span>');
|
||||
$this->assertEquals(highlight('+good', 'This is good'), 'This is <span class="highlight">good</span>');
|
||||
$this->assertEquals(highlight('-good', 'This is good'), 'This is good');
|
||||
$this->assertEquals(highlight('+good', 'This is goodness'), 'This is goodness');
|
||||
$this->assertEquals(highlight('good', 'This is goodness'), 'This is <span class="highlight">good</span>ness');
|
||||
}
|
||||
|
||||
function test_replace_ampersands() {
|
||||
$this->assertEquals(replace_ampersands_not_followed_by_entity("This & that "), "This & that ");
|
||||
$this->assertEquals(replace_ampersands_not_followed_by_entity("This   that "), "This &nbsp that ");
|
||||
}
|
||||
|
||||
function test_strip_links() {
|
||||
$this->assertEquals(strip_links('this is a <a href="http://someaddress.com/query">link</a>'), 'this is a link');
|
||||
}
|
||||
|
||||
function test_wikify_links() {
|
||||
$this->assertEquals(wikify_links('this is a <a href="http://someaddress.com/query">link</a>'), 'this is a link [ http://someaddress.com/query ]');
|
||||
}
|
||||
|
||||
function test_moodle_url_round_trip() {
|
||||
$strurl = 'http://moodle.org/course/view.php?id=5';
|
||||
$url = new moodle_url($strurl);
|
||||
$this->assertEquals($strurl, $url->out(false));
|
||||
|
||||
$strurl = 'http://moodle.org/user/index.php?contextid=53&sifirst=M&silast=D';
|
||||
$url = new moodle_url($strurl);
|
||||
$this->assertEquals($strurl, $url->out(false));
|
||||
}
|
||||
|
||||
function test_moodle_url_round_trip_array_params() {
|
||||
$strurl = 'http://example.com/?a%5B1%5D=1&a%5B2%5D=2';
|
||||
$url = new moodle_url($strurl);
|
||||
$this->assertEquals($strurl, $url->out(false));
|
||||
|
||||
$url = new moodle_url('http://example.com/?a[1]=1&a[2]=2');
|
||||
$this->assertEquals($strurl, $url->out(false));
|
||||
|
||||
// For un-keyed array params, we expect 0..n keys to be returned
|
||||
$strurl = 'http://example.com/?a%5B0%5D=0&a%5B1%5D=1';
|
||||
$url = new moodle_url('http://example.com/?a[]=0&a[]=1');
|
||||
$this->assertEquals($strurl, $url->out(false));
|
||||
}
|
||||
|
||||
function test_compare_url() {
|
||||
$url1 = new moodle_url('index.php', array('var1' => 1, 'var2' => 2));
|
||||
$url2 = new moodle_url('index2.php', array('var1' => 1, 'var2' => 2, 'var3' => 3));
|
||||
|
||||
$this->assertFalse($url1->compare($url2, URL_MATCH_BASE));
|
||||
$this->assertFalse($url1->compare($url2, URL_MATCH_PARAMS));
|
||||
$this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
|
||||
|
||||
$url2 = new moodle_url('index.php', array('var1' => 1, 'var3' => 3));
|
||||
|
||||
$this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
|
||||
$this->assertFalse($url1->compare($url2, URL_MATCH_PARAMS));
|
||||
$this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
|
||||
|
||||
$url2 = new moodle_url('index.php', array('var1' => 1, 'var2' => 2, 'var3' => 3));
|
||||
|
||||
$this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
|
||||
$this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
|
||||
$this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
|
||||
|
||||
$url2 = new moodle_url('index.php', array('var2' => 2, 'var1' => 1));
|
||||
|
||||
$this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
|
||||
$this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
|
||||
$this->assertTrue($url1->compare($url2, URL_MATCH_EXACT));
|
||||
}
|
||||
|
||||
function test_out_as_local_url() {
|
||||
$url1 = new moodle_url('/lib/tests/weblib_test.php');
|
||||
$this->assertEquals('/lib/tests/weblib_test.php', $url1->out_as_local_url());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @return void
|
||||
*/
|
||||
function test_out_as_local_url_error() {
|
||||
$url2 = new moodle_url('http://www.google.com/lib/simpletest/testweblib.php');
|
||||
$url2->out_as_local_url();
|
||||
}
|
||||
|
||||
public function test_clean_text() {
|
||||
$text = "lala <applet>xx</applet>";
|
||||
$this->assertEquals($text, clean_text($text, FORMAT_PLAIN));
|
||||
$this->assertEquals('lala xx', clean_text($text, FORMAT_MARKDOWN));
|
||||
$this->assertEquals('lala xx', clean_text($text, FORMAT_MOODLE));
|
||||
$this->assertEquals('lala xx', clean_text($text, FORMAT_HTML));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -2776,7 +2776,7 @@ function debugging($message = '', $level = DEBUG_NORMAL, $backtrace = null) {
|
||||
$forcedebug = in_array($USER->id, $debugusers);
|
||||
}
|
||||
|
||||
if (!$forcedebug and (empty($CFG->debug) || $CFG->debug < $level)) {
|
||||
if (!$forcedebug and (empty($CFG->debug) || ($CFG->debug != -1 and $CFG->debug < $level))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2789,7 +2789,7 @@ function debugging($message = '', $level = DEBUG_NORMAL, $backtrace = null) {
|
||||
$backtrace = debug_backtrace();
|
||||
}
|
||||
$from = format_backtrace($backtrace, CLI_SCRIPT);
|
||||
if (PHPUNITTEST) {
|
||||
if (PHPUNIT_TEST) {
|
||||
echo 'Debugging: ' . $message . "\n" . $from;
|
||||
|
||||
} else if (!empty($UNITTEST->running)) {
|
||||
|
||||
+15
-2
@@ -21,10 +21,23 @@
|
||||
<testsuite name="core_lib">
|
||||
<directory suffix="_test.php">lib/tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<testsuite name="core_ajax">
|
||||
<directory suffix="_test.php">lib/ajax/tests</directory>
|
||||
</testsuite>
|
||||
<testsuite name="core_ddl">
|
||||
<directory suffix="_test.php">lib/ddl/tests</directory>
|
||||
</testsuite>
|
||||
<testsuite name="core_dml">
|
||||
<directory suffix="_test.php">lib/dml/tests</directory>
|
||||
</testsuite>
|
||||
<testsuite name="core_form">
|
||||
<directory suffix="_test.php">lib/form/tests</directory>
|
||||
</testsuite>
|
||||
|
||||
<!--Plugin suites: use admin/tool/phpunit/cli/util.php to build phpunit.xml from phpunit.xml.dist with up-to-date list of plugins in current install-->
|
||||
<!--Plugin suites: use admin/tool/phpunit/cli/util.php to build phpunit.xml from phpunit.xml.dist with up-to-date list of plugins in current install-->
|
||||
<!--@plugin_suites_start@-->
|
||||
<!--@plugin_suites_end@-->
|
||||
|
||||
</testsuites>
|
||||
|
||||
</phpunit>
|
||||
|
||||
Reference in New Issue
Block a user