Merge branch 'w14_MDL-32149_m23_phpunit2' of git://github.com/skodak/moodle
This commit is contained in:
+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,131 @@
|
||||
<?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_testcase extends advanced_testcase {
|
||||
|
||||
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;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->enableajax = 1;
|
||||
$USER->ajax = 1;
|
||||
|
||||
// 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
@@ -10767,17 +10767,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+45
-18
@@ -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,19 @@ 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_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);
|
||||
@@ -55,10 +62,16 @@ define('NO_OUTPUT_BUFFERING', true);
|
||||
define('ABORT_AFTER_CONFIG', true);
|
||||
require(__DIR__ . '/../../config.php');
|
||||
|
||||
if (!defined('PHPUNIT_LONGTEST')) {
|
||||
/** Execute longer version of tests */
|
||||
define('PHPUNIT_LONGTEST', false);
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
|
||||
//=========================================================
|
||||
@@ -200,7 +225,9 @@ function phpunit_bootstrap_error($text, $errorcode = 1) {
|
||||
function phpunit_bootstrap_initdataroot($dataroot) {
|
||||
global $CFG;
|
||||
|
||||
file_put_contents("$dataroot/phpunittestdir.txt", 'Contents of this directory are used during tests only, do not delete this file!');
|
||||
if (!file_exists("$dataroot/phpunittestdir.txt")) {
|
||||
file_put_contents("$dataroot/phpunittestdir.txt", 'Contents of this directory are used during tests only, do not delete this file!');
|
||||
}
|
||||
chmod("$dataroot/phpunittestdir.txt", $CFG->filepermissions);
|
||||
if (!file_exists("$CFG->phpunit_dataroot/phpunit")) {
|
||||
mkdir("$CFG->phpunit_dataroot/phpunit", $CFG->directorypermissions);
|
||||
|
||||
@@ -0,0 +1,470 @@
|
||||
<?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();
|
||||
|
||||
/**
|
||||
* Data generator for unit tests
|
||||
*/
|
||||
class phpunit_data_generator {
|
||||
protected $usercounter = 0;
|
||||
protected $categorycount = 0;
|
||||
protected $coursecount = 0;
|
||||
protected $blockcount = 0;
|
||||
protected $modulecount = 0;
|
||||
protected $scalecount = 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;
|
||||
$this->scalecount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test user
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass user record
|
||||
*/
|
||||
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 course category record
|
||||
*/
|
||||
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 with keys:
|
||||
* 'createsections'=>bool precreate all sections
|
||||
* @return stdClass course record
|
||||
*/
|
||||
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);
|
||||
|
||||
if (!empty($options['createsections'])) {
|
||||
for($i=1; $i<$record['numsections']; $i++) {
|
||||
self::create_course_section(array('course'=>$course->id, 'section'=>$i));
|
||||
}
|
||||
}
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create course section if does not exist yet
|
||||
* @param mixed $record
|
||||
* @param array|null $options
|
||||
* @return stdClass
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function create_course_section($record = null, array $options = null) {
|
||||
global $DB;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (empty($record['course'])) {
|
||||
throw new coding_exception('course must be present in phpunit_util::create_course_section() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['section'])) {
|
||||
throw new coding_exception('section must be present in phpunit_util::create_course_section() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['summary'])) {
|
||||
$record['summary'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['summaryformat'])) {
|
||||
$record['summaryformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if ($section = $DB->get_record('course_sections', array('course'=>$record['course'], 'section'=>$record['section']))) {
|
||||
return $section;
|
||||
}
|
||||
|
||||
$section = new stdClass();
|
||||
$section->course = $record['course'];
|
||||
$section->section = $record['section'];
|
||||
$section->name = $record['name'];
|
||||
$section->summary = $record['summary'];
|
||||
$section->summaryformat = $record['summaryformat'];
|
||||
$id = $DB->insert_record('course_sections', $section);
|
||||
|
||||
return $DB->get_record('course_sections', array('id'=>$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test block
|
||||
* @param string $blockname
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass block instance record
|
||||
*/
|
||||
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 activity record
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test scale
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass block instance record
|
||||
*/
|
||||
public function create_scale($record=null, array $options=null) {
|
||||
global $DB;
|
||||
|
||||
$this->scalecount++;
|
||||
$i = $this->scalecount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'Test scale '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['scale'])) {
|
||||
$record['scale'] = 'A,B,C,D,F';
|
||||
}
|
||||
|
||||
if (!isset($record['courseid'])) {
|
||||
$record['courseid'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['userid'])) {
|
||||
$record['userid'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = 'Test scale description '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['descriptionformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$record['timemodified'] = time();
|
||||
|
||||
if (isset($record['id'])) {
|
||||
$DB->import_record('scale', $record);
|
||||
$DB->get_manager()->reset_sequence('scale');
|
||||
$id = $record['id'];
|
||||
} else {
|
||||
$id = $DB->insert_record('scale', $record);
|
||||
}
|
||||
|
||||
return $DB->get_record('scale', array('id'=>$id), '*', MUST_EXIST);
|
||||
}
|
||||
}
|
||||
+503
-98
@@ -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,133 @@ 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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
$tables = $DB->get_tables(false);
|
||||
if (!$tables or empty($tables['config'])) {
|
||||
// not installed yet
|
||||
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;
|
||||
$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
|
||||
|
||||
$resetseq = array();
|
||||
foreach ($data as $table=>$records) {
|
||||
if (empty($records)) {
|
||||
if ($DB->count_records($table)) {
|
||||
$DB->delete_records($table, array());
|
||||
$resetseq[$table] = $table;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$firstrecord = reset($records);
|
||||
if (property_exists($firstrecord, 'id')) {
|
||||
if ($DB->count_records($table) >= count($records)) {
|
||||
$currentrecords = $DB->get_records($table, array(), 'id ASC');
|
||||
$changed = false;
|
||||
foreach ($records as $id=>$record) {
|
||||
if (!isset($currentrecords[$id])) {
|
||||
$changed = true;
|
||||
break;
|
||||
}
|
||||
if ((array)$record != (array)$currentrecords[$id]) {
|
||||
$changed = true;
|
||||
break;
|
||||
}
|
||||
unset($currentrecords[$id]);
|
||||
}
|
||||
if (!$changed) {
|
||||
if ($currentrecords) {
|
||||
$remainingfirst = reset($currentrecords);
|
||||
$lastrecord = end($records);
|
||||
if ($remainingfirst->id > $lastrecord->id) {
|
||||
$DB->delete_records_select($table, "id >= ?", array($remainingfirst->id));
|
||||
$resetseq[$table] = $table;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$DB->delete_records($table, array());
|
||||
if (property_exists($firstrecord, 'id')) {
|
||||
$resetseq[$table] = $table;
|
||||
}
|
||||
foreach ($records as $record) {
|
||||
$DB->import_record($table, $record, false, true);
|
||||
}
|
||||
}
|
||||
// reset all sequences
|
||||
foreach ($resetseq as $table) {
|
||||
$DB->get_manager()->reset_sequence($table, true);
|
||||
}
|
||||
|
||||
$trans->allow_commit();
|
||||
|
||||
// remove extra tables
|
||||
foreach ($tables as $tablename) {
|
||||
if (!isset($data[$tablename])) {
|
||||
$DB->get_manager()->drop_table(new xmldb_table($tablename));
|
||||
}
|
||||
}
|
||||
$dbreset = true;
|
||||
}
|
||||
}
|
||||
|
||||
$data = self::get_tabledata();
|
||||
self::$lastdbwrites = $DB->perf_get_writes();
|
||||
|
||||
foreach($data['config'] as $record) {
|
||||
$name = $record->name;
|
||||
$value = $record->value;
|
||||
if (property_exists($CFG, $name)) {
|
||||
// config.php settings always take precedence
|
||||
return $dbreset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge dataroot
|
||||
* @static
|
||||
* @return void
|
||||
*/
|
||||
public static function reset_dataroot() {
|
||||
global $CFG;
|
||||
|
||||
$handle = opendir($CFG->dataroot);
|
||||
$skip = array('.', '..', 'phpunittestdir.txt', 'phpunit', '.htaccess');
|
||||
while (false !== ($item = readdir($handle))) {
|
||||
if (in_array($item, $skip)) {
|
||||
continue;
|
||||
}
|
||||
$CFG->{$name} = $value;
|
||||
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');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,47 +231,106 @@ 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, $SITE, $COURSE, $PAGE, $OUTPUT, $SESSION;
|
||||
|
||||
$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');
|
||||
$oldsite = self::get_global_backup('SITE');
|
||||
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);
|
||||
}
|
||||
|
||||
if ($COURSE->id != $oldsite->id) {
|
||||
error_log('warning: unexpected change of $COURSE'.$where);
|
||||
}
|
||||
}
|
||||
$trans->allow_commit();
|
||||
|
||||
purge_all_caches();
|
||||
// restore _SERVER
|
||||
unset($_SERVER['HTTP_USER_AGENT']);
|
||||
|
||||
// restore original config
|
||||
$CFG = self::get_global_backup('CFG');
|
||||
$SITE = self::get_global_backup('SITE');
|
||||
$COURSE = $SITE;
|
||||
|
||||
// recreate globals
|
||||
$OUTPUT = new bootstrap_renderer();
|
||||
$PAGE = new moodle_page();
|
||||
$FULLME = null;
|
||||
$ME = null;
|
||||
$SCRIPT = null;
|
||||
$SESSION = new stdClass();
|
||||
$_SESSION['SESSION'] =& $SESSION;
|
||||
|
||||
// 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
|
||||
self::reset_dataroot();
|
||||
|
||||
// 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() {
|
||||
global $CFG;
|
||||
public static function bootstrap_init() {
|
||||
global $CFG, $SITE;
|
||||
|
||||
// backup the globals
|
||||
self::$globals['CFG'] = clone($CFG);
|
||||
self::$globals['SITE'] = clone($SITE);
|
||||
|
||||
// refresh data in all tables, clear caches, etc.
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +363,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 +384,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,18 +437,17 @@ class phpunit_util {
|
||||
}
|
||||
|
||||
// drop dataroot
|
||||
remove_dir($CFG->dataroot, true);
|
||||
self::reset_dataroot();
|
||||
phpunit_bootstrap_initdataroot($CFG->dataroot);
|
||||
remove_dir("$CFG->dataroot/phpunit", true);
|
||||
|
||||
// drop all tables
|
||||
$trans = $DB->start_delegated_transaction();
|
||||
$tables = $DB->get_tables(false);
|
||||
foreach ($tables as $tablename) {
|
||||
$DB->delete_records($tablename, array());
|
||||
if (isset($tables['config'])) {
|
||||
// config always last to prevent problems with interrupted drops!
|
||||
unset($tables['config']);
|
||||
$tables['config'] = 'config';
|
||||
}
|
||||
$trans->allow_commit();
|
||||
|
||||
// now drop them
|
||||
foreach ($tables as $tablename) {
|
||||
$table = new xmldb_table($tablename);
|
||||
$DB->get_manager()->drop_table($table);
|
||||
@@ -296,8 +480,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');
|
||||
@@ -306,7 +491,13 @@ class phpunit_util {
|
||||
$data = array();
|
||||
$tables = $DB->get_tables();
|
||||
foreach ($tables as $table) {
|
||||
$data[$table] = $DB->get_records($table, array());
|
||||
$columns = $DB->get_columns($table);
|
||||
if (isset($columns['id'])) {
|
||||
$data[$table] = $DB->get_records($table, array(), 'id ASC');
|
||||
} else {
|
||||
// there should not be many of these
|
||||
$data[$table] = $DB->get_records($table, array());
|
||||
}
|
||||
}
|
||||
$data = serialize($data);
|
||||
@unlink("$CFG->dataroot/phpunit/tabledata.ser");
|
||||
@@ -319,7 +510,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 +563,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 +616,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 +630,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 +645,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 +656,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 +668,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 +680,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 +692,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 +704,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 +716,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 +727,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
|
||||
@@ -541,17 +739,58 @@ class basic_testcase extends PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* Note: use setUp() or setUpBeforeClass() in custom test cases.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
public function __construct($name = NULL, array $data = array(), $dataName = '') {
|
||||
final public function __construct($name = null, array $data = array(), $dataName = '') {
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(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? null means log changes */
|
||||
protected $resetAfterTest;
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* Note: use setUp() or setUpBeforeClass() in custom test cases.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
final public function __construct($name = null, array $data = array(), $dataName = '') {
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(false);
|
||||
$this->setInIsolation(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -559,43 +798,209 @@ 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current $USER, reset access cache.
|
||||
* @static
|
||||
* @param null|int|stdClass $user user record, null means non-logged-in, integer means userid
|
||||
* @return void
|
||||
*/
|
||||
public static function setUser($user = null) {
|
||||
global $CFG, $DB;
|
||||
|
||||
if (is_object($user)) {
|
||||
$user = clone($user);
|
||||
} else if (!$user) {
|
||||
$user = new stdClass();
|
||||
$user->id = 0;
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
} else {
|
||||
$user = $DB->get_record('user', array('id'=>$user));
|
||||
}
|
||||
unset($user->description);
|
||||
unset($user->access);
|
||||
|
||||
session_set_user($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 method of this class 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 ignored. 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special test case for testing of DML drivers and DDL layer.
|
||||
*
|
||||
* Note: Use only 'test_table*' when creating new tables.
|
||||
*
|
||||
* @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;
|
||||
|
||||
/** @var moodle_database */
|
||||
protected $tdb;
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
final 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;
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
global $DB;
|
||||
|
||||
if (self::$extradb) {
|
||||
$this->tdb = self::$extradb;
|
||||
} else {
|
||||
$this->tdb = $DB;
|
||||
}
|
||||
}
|
||||
|
||||
protected 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();
|
||||
}
|
||||
}
|
||||
|
||||
+23
-11
@@ -2,11 +2,18 @@ PHPUnit testing support in Moodle
|
||||
==================================
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
* [Moodle Dev wiki](http://docs.moodle.org/dev/PHPUnit)
|
||||
* [PHPUnit online documentaion](http://www.phpunit.de/manual/current/en/)
|
||||
* [MDL-32323](http://tracker.moodle.org/browse/MDL-32323), [MDL-32149](http://tracker.moodle.org/browse/MDL-32149), [MDL-31857](http://tracker.moodle.org/browse/MDL-31857)
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
1. install PHPUnit PEAR extension - see [PHPUnit docs](http://www.phpunit.de/manual/current/en/installation.html) for more details
|
||||
2. edit main config.php - add $CFG->phpunit_prefix and $CFG->phpunit_dataroot - see config-dist.php for more details
|
||||
3. execute `php admin/tool/phpunit/cli/util.php --install` to initialise test database
|
||||
3. execute `php admin/tool/phpunit/cli/util.php --install` from dirroot to initialise test database and dataroot
|
||||
4. it is necessary to reinitialise the test database manually after every upgrade or installation of new plugins
|
||||
|
||||
|
||||
@@ -19,15 +26,17 @@ Test execution
|
||||
* it is possible to create custom configuration files in xml format and use `phpunit -c myconfig.xml`
|
||||
|
||||
|
||||
How to add more tests
|
||||
---------------------
|
||||
1. create `tests` directory in any plugin
|
||||
2. add `*_test.php` files with custom class that extends `basic_testcase`
|
||||
3. manually add all core unit test locations to `phpunit.xml.dist`
|
||||
How to add more tests?
|
||||
----------------------
|
||||
1. create `tests` directory in your plugin if does not already exist
|
||||
2. add `*_test.php` files with custom class that extends `basic_testcase` or `advanced_testcase`
|
||||
3. execute your new test, for example `phpunit core_phpunit_basic_testcase local/mytest/tests/mytest_test.php`
|
||||
4. optionally build new phpunit.xml by executing `php admin/tool/phpunit/cli/util.php --buildconfig` and run all tests
|
||||
5. core developers have to add all core unit test locations to `phpunit.xml.dist`
|
||||
|
||||
|
||||
How to convert existing tests
|
||||
-----------------------------
|
||||
How to convert existing tests?
|
||||
------------------------------
|
||||
1. create new test file in `xxx/tests/yyy_test.php`
|
||||
2. copy contents of the old test file
|
||||
3. replace `extends UnitTestCase` with `extends basic_testcase`
|
||||
@@ -44,6 +53,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
|
||||
* delete all simpletests
|
||||
* hide old SimpleTests in UI and delete Functional DB tests
|
||||
* shell script that prepares everything for the first execution
|
||||
* optional 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'
|
||||
),
|
||||
|
||||
@@ -1070,6 +1070,13 @@ function session_set_user($user) {
|
||||
$_SESSION['USER'] = $user;
|
||||
unset($_SESSION['USER']->description); // conserve memory
|
||||
sesskey(); // init session key
|
||||
|
||||
if (PHPUNIT_TEST) {
|
||||
// phpunit tests use reversed reference
|
||||
global $USER;
|
||||
$USER = $_SESSION['USER'];
|
||||
$_SESSION['USER'] =& $USER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+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
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.org //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Unit tests for ../portfoliolib.php.
|
||||
*
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package moodlecore
|
||||
*/
|
||||
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
|
||||
}
|
||||
|
||||
require_once($CFG->libdir . '/portfoliolib.php');
|
||||
|
||||
class portfoliolibaddbutton_test extends UnitTestCaseUsingDatabase {
|
||||
|
||||
public static $includecoverage = array('lib/portfoliolib.php');
|
||||
|
||||
protected $testtables = array(
|
||||
'lib' => array(
|
||||
'portfolio_instance', 'portfolio_instance_user'));
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->switch_to_test_db(); // Switch to test DB for all the execution
|
||||
|
||||
foreach ($this->testtables as $dir => $tables) {
|
||||
$this->create_test_tables($tables, $dir); // Create tables
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
parent::tearDown(); // In charge of droppng all the test tables
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: The portfolio unit tests were obselete and did not work.
|
||||
* They have been commented out so that they do not break the
|
||||
* unit tests in Moodle 2.
|
||||
*
|
||||
* At some point:
|
||||
* 1. These tests should be audited to see which ones were valuable.
|
||||
* 2. The useful ones should be rewritten using the current standards
|
||||
* for writing test cases.
|
||||
*
|
||||
* This might be left until Moodle 2.1 when the test case framework
|
||||
* is due to change.
|
||||
*/
|
||||
/*
|
||||
* A test of setting and getting formats. What is returned in the getter is a combination of what is explicitly set in
|
||||
* the button, and what is set in the static method of the export class.
|
||||
*
|
||||
* In some cases they conflict, in which case the button wins.
|
||||
*/
|
||||
|
||||
/*
|
||||
function test_set_formats() {
|
||||
|
||||
$button = new portfolio_add_button();
|
||||
$button->set_callback_options('assignment_portfolio_caller', array('id' => 6), '/mod/assignment/locallib.php');
|
||||
$formats = array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_IMAGE);
|
||||
$button->set_formats($formats);
|
||||
|
||||
// Expecting $formats + assignment_portfolio_caller::base_supported_formats merged to unique values.
|
||||
$formats_combined = array_unique(array_merge($formats, assignment_portfolio_caller::base_supported_formats()));
|
||||
|
||||
// In this case, neither file or image conflict with leap2a, which is why all three are returned.
|
||||
$this->assertEqual(count($formats_combined), count($button->get_formats()));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.org //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Unit tests for ../portfoliolib.php.
|
||||
*
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package moodlecore
|
||||
*/
|
||||
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
|
||||
}
|
||||
|
||||
require_once($CFG->libdir . '/simpletest/portfolio_testclass.php');
|
||||
|
||||
// Load tests for various modules
|
||||
foreach (get_list_of_plugins('mod') as $module) {
|
||||
$modtest = $CFG->dirroot . '/mod/' . $module . '/simpletest/test_' . $module . '_portfolio_callers.php';
|
||||
if (file_exists($modtest)) {
|
||||
require_once($modtest);
|
||||
}
|
||||
}
|
||||
|
||||
class empty_portfoliolib_test extends UnitTestCase {
|
||||
// empty, this prevents warning in coverage report
|
||||
}
|
||||
@@ -0,0 +1,985 @@
|
||||
<?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
|
||||
*
|
||||
* @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']);
|
||||
$userids = array_values($testusers);
|
||||
$userids[] = get_admin()->id;
|
||||
|
||||
if (!PHPUNIT_LONGTEST) {
|
||||
$contexts = array_slice($contexts, 0, 10);
|
||||
$capabilities = array_slice($capabilities, 0, 5);
|
||||
$userids = array_slice($userids, 0, 5);
|
||||
}
|
||||
|
||||
// Random time!
|
||||
//srand(666);
|
||||
foreach($userids as $userid) { // no guest or deleted
|
||||
// each user gets 0-10 random roles
|
||||
$rcount = rand(0, 10);
|
||||
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);
|
||||
$maxoverrides = count($contexts)*10;
|
||||
for($j=0; $j<$maxoverrides; $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);
|
||||
|
||||
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();
|
||||
|
||||
$userids[] = $CFG->siteguest;
|
||||
$userids[] = 0; // not-logged-in user
|
||||
$userids[] = -1; // non-existent user
|
||||
|
||||
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 ($userids as $userid) {
|
||||
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($userids);
|
||||
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;
|
||||
|
||||
protected 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);
|
||||
}
|
||||
|
||||
protected 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_testcase 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,366 @@
|
||||
<?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 conditional activities
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright © 2008 The Open University
|
||||
* @author Sam Marshall
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/lib/conditionlib.php');
|
||||
|
||||
|
||||
class conditionlib_testcase extends advanced_testcase {
|
||||
protected function setUp() {
|
||||
global $CFG;
|
||||
parent::setUp();
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->enableavailability = 1;
|
||||
$CFG->enablecompletion = 1;
|
||||
}
|
||||
|
||||
function test_constructor() {
|
||||
global $DB,$CFG;
|
||||
$cm=new stdClass;
|
||||
|
||||
// Test records
|
||||
$id=$DB->insert_record('course_modules',(object)array(
|
||||
'showavailability'=>1,'availablefrom'=>17,'availableuntil'=>398,'course'=>64));
|
||||
|
||||
// no ID
|
||||
try {
|
||||
$test=new condition_info($cm);
|
||||
$this->fail();
|
||||
} catch(coding_exception $e) {
|
||||
}
|
||||
|
||||
// no other data
|
||||
$cm->id=$id;
|
||||
$test=new condition_info($cm,CONDITION_MISSING_EVERYTHING);
|
||||
$this->assertEquals(
|
||||
(object)array('id'=>$id,'showavailability'=>1,
|
||||
'availablefrom'=>17,'availableuntil'=>398,'course'=>64,
|
||||
'conditionsgrade'=>array(), 'conditionscompletion'=>array()),
|
||||
$test->get_full_course_module());
|
||||
|
||||
// just the course_modules stuff; check it doesn't request that from db
|
||||
$cm->showavailability=0;
|
||||
$cm->availablefrom=2;
|
||||
$cm->availableuntil=74;
|
||||
$cm->course=38;
|
||||
$test=new condition_info($cm,CONDITION_MISSING_EXTRATABLE);
|
||||
$this->assertEquals(
|
||||
(object)array('id'=>$id,'showavailability'=>0,
|
||||
'availablefrom'=>2,'availableuntil'=>74,'course'=>38,
|
||||
'conditionsgrade'=>array(), 'conditionscompletion'=>array()),
|
||||
$test->get_full_course_module());
|
||||
|
||||
// Now let's add some actual grade/completion conditions
|
||||
$DB->insert_record('course_modules_availability',(object)array(
|
||||
'coursemoduleid'=>$id,
|
||||
'sourcecmid'=>42,
|
||||
'requiredcompletion'=>2
|
||||
));
|
||||
$DB->insert_record('course_modules_availability',(object)array(
|
||||
'coursemoduleid'=>$id,
|
||||
'sourcecmid'=>666,
|
||||
'requiredcompletion'=>1
|
||||
));
|
||||
$DB->insert_record('course_modules_availability',(object)array(
|
||||
'coursemoduleid'=>$id,
|
||||
'gradeitemid'=>37,
|
||||
'grademin'=>5.5
|
||||
));
|
||||
|
||||
$cm=(object)array('id'=>$id);
|
||||
$test=new condition_info($cm,CONDITION_MISSING_EVERYTHING);
|
||||
$fullcm=$test->get_full_course_module();
|
||||
$this->assertEquals(array(42=>2,666=>1),$fullcm->conditionscompletion);
|
||||
$this->assertEquals(array(37=>(object)array('min'=>5.5,'max'=>null,'name'=>'!missing')),
|
||||
$fullcm->conditionsgrade);
|
||||
}
|
||||
|
||||
private function make_course() {
|
||||
global $DB;
|
||||
$categoryid=$DB->insert_record('course_categories',(object)array('name'=>'conditionlibtest'));
|
||||
return $DB->insert_record('course',(object)array(
|
||||
'fullname'=>'Condition test','shortname'=>'CT1',
|
||||
'category'=>$categoryid,'enablecompletion'=>1));
|
||||
}
|
||||
|
||||
private function make_course_module($courseid,$params=array()) {
|
||||
global $DB;
|
||||
static $moduleid=0;
|
||||
if(!$moduleid) {
|
||||
$moduleid=$DB->get_field('modules','id',array('name'=>'resource'));
|
||||
}
|
||||
|
||||
$rid=$DB->insert_record('resource',(object)array('course'=>$courseid,
|
||||
'name'=>'xxx','alltext'=>'','popup'=>''));
|
||||
$settings=(object)array(
|
||||
'course'=>$courseid,'module'=>$moduleid,'instance'=>$rid);
|
||||
foreach($params as $name=>$value) {
|
||||
$settings->{$name}=$value;
|
||||
}
|
||||
return $DB->insert_record('course_modules',$settings);
|
||||
}
|
||||
|
||||
private function make_section($courseid,$cmids,$sectionnum=0) {
|
||||
global $DB;
|
||||
$DB->insert_record('course_sections',(object)array(
|
||||
'course'=>$courseid,'sequence'=>implode(',',$cmids),'section'=>$sectionnum));
|
||||
}
|
||||
|
||||
function test_modinfo() {
|
||||
global $DB;
|
||||
|
||||
// Let's make a course
|
||||
$courseid=$this->make_course();
|
||||
|
||||
// Now let's make a couple modules on that course
|
||||
$cmid1=$this->make_course_module($courseid,array(
|
||||
'showavailability'=>1,'availablefrom'=>17,'availableuntil'=>398,
|
||||
'completion'=>COMPLETION_TRACKING_MANUAL));
|
||||
$cmid2=$this->make_course_module($courseid,array(
|
||||
'showavailability'=>0,'availablefrom'=>0,'availableuntil'=>0));
|
||||
$this->make_section($courseid,array($cmid1,$cmid2));
|
||||
|
||||
// Add a fake grade item
|
||||
$gradeitemid=$DB->insert_record('grade_items',(object)array(
|
||||
'courseid'=>$courseid,'itemname'=>'frog'));
|
||||
|
||||
// One of the modules has grade and completion conditions, other doesn't
|
||||
$DB->insert_record('course_modules_availability',(object)array(
|
||||
'coursemoduleid'=>$cmid2,
|
||||
'sourcecmid'=>$cmid1,
|
||||
'requiredcompletion'=>1
|
||||
));
|
||||
$DB->insert_record('course_modules_availability',(object)array(
|
||||
'coursemoduleid'=>$cmid2,
|
||||
'gradeitemid'=>$gradeitemid,
|
||||
'grademin'=>5.5
|
||||
));
|
||||
|
||||
// Okay sweet, now get modinfo
|
||||
$course = $DB->get_record('course',array('id'=>$courseid));
|
||||
$modinfo=get_fast_modinfo($course);
|
||||
|
||||
// Test basic data
|
||||
$this->assertEquals(1,$modinfo->cms[$cmid1]->showavailability);
|
||||
$this->assertEquals(17,$modinfo->cms[$cmid1]->availablefrom);
|
||||
$this->assertEquals(398,$modinfo->cms[$cmid1]->availableuntil);
|
||||
$this->assertEquals(0,$modinfo->cms[$cmid2]->showavailability);
|
||||
$this->assertEquals(0,$modinfo->cms[$cmid2]->availablefrom);
|
||||
$this->assertEquals(0,$modinfo->cms[$cmid2]->availableuntil);
|
||||
|
||||
// Test condition arrays
|
||||
$this->assertEquals(array(),$modinfo->cms[$cmid1]->conditionscompletion);
|
||||
$this->assertEquals(array(),$modinfo->cms[$cmid1]->conditionsgrade);
|
||||
$this->assertEquals(array($cmid1=>1),
|
||||
$modinfo->cms[$cmid2]->conditionscompletion);
|
||||
$this->assertEquals(array($gradeitemid=>(object)array('min'=>5.5,'max'=>null,'name'=>'frog')),
|
||||
$modinfo->cms[$cmid2]->conditionsgrade);
|
||||
}
|
||||
|
||||
function test_add_and_remove() {
|
||||
global $DB;
|
||||
// Make course and module
|
||||
$courseid=$this->make_course();
|
||||
$cmid=$this->make_course_module($courseid,array(
|
||||
'showavailability'=>0,'availablefrom'=>0,'availableuntil'=>0));
|
||||
$this->make_section($courseid,array($cmid));
|
||||
|
||||
// Check it has no conditions
|
||||
$test1=new condition_info((object)array('id'=>$cmid),
|
||||
CONDITION_MISSING_EVERYTHING);
|
||||
$cm=$test1->get_full_course_module();
|
||||
$this->assertEquals(array(),$cm->conditionscompletion);
|
||||
$this->assertEquals(array(),$cm->conditionsgrade);
|
||||
|
||||
// Add conditions of each type
|
||||
$test1->add_completion_condition(13,3);
|
||||
$this->assertEquals(array(13=>3),$cm->conditionscompletion);
|
||||
$test1->add_grade_condition(666,0.4,null,true);
|
||||
$this->assertEquals(array(666=>(object)array('min'=>0.4,'max'=>null,'name'=>'!missing')),
|
||||
$cm->conditionsgrade);
|
||||
|
||||
// Check they were really added in db
|
||||
$test2=new condition_info((object)array('id'=>$cmid),
|
||||
CONDITION_MISSING_EVERYTHING);
|
||||
$cm=$test2->get_full_course_module();
|
||||
$this->assertEquals(array(13=>3),$cm->conditionscompletion);
|
||||
$this->assertEquals(array(666=>(object)array('min'=>0.4,'max'=>null,'name'=>'!missing')),
|
||||
$cm->conditionsgrade);
|
||||
|
||||
// Wipe conditions
|
||||
$test2->wipe_conditions();
|
||||
$this->assertEquals(array(),$cm->conditionscompletion);
|
||||
$this->assertEquals(array(),$cm->conditionsgrade);
|
||||
|
||||
// Check they were really wiped
|
||||
$test3=new condition_info((object)array('id'=>$cmid),
|
||||
CONDITION_MISSING_EVERYTHING);
|
||||
$cm=$test3->get_full_course_module();
|
||||
$this->assertEquals(array(),$cm->conditionscompletion);
|
||||
$this->assertEquals(array(),$cm->conditionsgrade);
|
||||
}
|
||||
|
||||
function test_is_available() {
|
||||
global $DB,$USER;
|
||||
$courseid=$this->make_course();
|
||||
|
||||
// No conditions
|
||||
$cmid=$this->make_course_module($courseid);
|
||||
$ci=new condition_info((object)array('id'=>$cmid),
|
||||
CONDITION_MISSING_EVERYTHING);
|
||||
$this->assertTrue($ci->is_available($text,false,0));
|
||||
$this->assertEquals('',$text);
|
||||
|
||||
// Time (from)
|
||||
$time=time()+100;
|
||||
$cmid=$this->make_course_module($courseid,array('availablefrom'=>$time));
|
||||
$ci=new condition_info((object)array('id'=>$cmid),
|
||||
CONDITION_MISSING_EVERYTHING);
|
||||
$this->assertFalse($ci->is_available($text));
|
||||
$this->assertRegExp('/'.preg_quote(userdate($time,get_string('strftimedate','langconfig'))).'/',$text);
|
||||
|
||||
$time=time()-100;
|
||||
$cmid=$this->make_course_module($courseid,array('availablefrom'=>$time));
|
||||
$ci=new condition_info((object)array('id'=>$cmid),
|
||||
CONDITION_MISSING_EVERYTHING);
|
||||
$this->assertTrue($ci->is_available($text));
|
||||
$this->assertEquals('',$text);
|
||||
$this->assertRegExp('/'.preg_quote(userdate($time,get_string('strftimedate','langconfig'))).'/',$ci->get_full_information());
|
||||
|
||||
// Time (until)
|
||||
$cmid=$this->make_course_module($courseid,array('availableuntil'=>time()-100));
|
||||
$ci=new condition_info((object)array('id'=>$cmid),
|
||||
CONDITION_MISSING_EVERYTHING);
|
||||
$this->assertFalse($ci->is_available($text));
|
||||
$this->assertEquals('',$text);
|
||||
|
||||
// Completion
|
||||
$oldid=$cmid;
|
||||
$cmid=$this->make_course_module($courseid);
|
||||
$this->make_section($courseid,array($oldid,$cmid));
|
||||
$oldcm=$DB->get_record('course_modules',array('id'=>$oldid));
|
||||
$oldcm->completion=COMPLETION_TRACKING_MANUAL;
|
||||
$DB->update_record('course_modules',$oldcm);
|
||||
|
||||
// Need to reset modinfo after changing the options
|
||||
rebuild_course_cache($courseid);
|
||||
$reset = 'reset';
|
||||
get_fast_modinfo($reset);
|
||||
|
||||
$ci=new condition_info((object)array('id'=>$cmid),CONDITION_MISSING_EVERYTHING);
|
||||
$ci->add_completion_condition($oldid,COMPLETION_COMPLETE);
|
||||
condition_info::wipe_session_cache();
|
||||
|
||||
$this->assertFalse($ci->is_available($text,false));
|
||||
$this->assertEquals(get_string('requires_completion_1','condition','xxx'),$text);
|
||||
completion_info::wipe_session_cache();
|
||||
$completion=new completion_info($DB->get_record('course',array('id'=>$courseid)));
|
||||
$completion->update_state($oldcm,COMPLETION_COMPLETE);
|
||||
completion_info::wipe_session_cache();
|
||||
condition_info::wipe_session_cache();
|
||||
|
||||
$this->assertTrue($ci->is_available($text));
|
||||
$this->assertFalse($ci->is_available($text,false,$USER->id+1));
|
||||
completion_info::wipe_session_cache();
|
||||
condition_info::wipe_session_cache();
|
||||
$completion=new completion_info($DB->get_record('course',array('id'=>$courseid)));
|
||||
$completion->update_state($oldcm,COMPLETION_INCOMPLETE);
|
||||
$this->assertFalse($ci->is_available($text));
|
||||
|
||||
$ci->wipe_conditions();
|
||||
$ci->add_completion_condition($oldid,COMPLETION_INCOMPLETE);
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertTrue($ci->is_available($text));
|
||||
$this->assertTrue($ci->is_available($text,false,$USER->id+1));
|
||||
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertTrue($ci->is_available($text,true));
|
||||
|
||||
// Grade
|
||||
$ci->wipe_conditions();
|
||||
// Add a fake grade item
|
||||
$gradeitemid=$DB->insert_record('grade_items',(object)array(
|
||||
'courseid'=>$courseid,'itemname'=>'frog'));
|
||||
// Add a condition on a value existing...
|
||||
$ci->add_grade_condition($gradeitemid,null,null,true);
|
||||
$this->assertFalse($ci->is_available($text));
|
||||
$this->assertEquals(get_string('requires_grade_any','condition','frog'),$text);
|
||||
|
||||
// Fake it existing
|
||||
$DB->insert_record('grade_grades',(object)array(
|
||||
'itemid'=>$gradeitemid,'userid'=>$USER->id,'finalgrade'=>3.78));
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertTrue($ci->is_available($text));
|
||||
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertTrue($ci->is_available($text,true));
|
||||
|
||||
// Now require that user gets more than 3.78001
|
||||
$ci->wipe_conditions();
|
||||
$ci->add_grade_condition($gradeitemid,3.78001,null,true);
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertFalse($ci->is_available($text));
|
||||
$this->assertEquals(get_string('requires_grade_min','condition','frog'),$text);
|
||||
|
||||
// ...just on 3.78...
|
||||
$ci->wipe_conditions();
|
||||
$ci->add_grade_condition($gradeitemid,3.78,null,true);
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertTrue($ci->is_available($text));
|
||||
|
||||
// ...less than 3.78
|
||||
$ci->wipe_conditions();
|
||||
$ci->add_grade_condition($gradeitemid,null,3.78,true);
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertFalse($ci->is_available($text));
|
||||
$this->assertEquals(get_string('requires_grade_max','condition','frog'),$text);
|
||||
|
||||
// ...less than 3.78001
|
||||
$ci->wipe_conditions();
|
||||
$ci->add_grade_condition($gradeitemid,null,3.78001,true);
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertTrue($ci->is_available($text));
|
||||
|
||||
// ...in a range that includes it
|
||||
$ci->wipe_conditions();
|
||||
$ci->add_grade_condition($gradeitemid,3,4,true);
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertTrue($ci->is_available($text));
|
||||
|
||||
// ...in a range that doesn't include it
|
||||
$ci->wipe_conditions();
|
||||
$ci->add_grade_condition($gradeitemid,4,5,true);
|
||||
condition_info::wipe_session_cache();
|
||||
$this->assertFalse($ci->is_available($text));
|
||||
$this->assertEquals(get_string('requires_grade_range','condition','frog'),$text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,721 @@
|
||||
<?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_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Sets up the test class
|
||||
*/
|
||||
protected 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));
|
||||
|
||||
|
||||
$cssin = '#nextLink{background:url(data:image/gif;base64,AAAA);}';
|
||||
$cssout = '#nextLink{background-image:url(data:image/gif;base64,AAAA);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '#nextLink{background-image:url(data:image/gif;base64,AAAA);}';
|
||||
$cssout = '#nextLink{background-image:url(data:image/gif;base64,AAAA);}';
|
||||
$this->assertEquals($cssout, $optimiser->process($cssin));
|
||||
|
||||
$cssin = '.test {background: #123456 url(data:image/gif;base64,AAAA) no-repeat top left;}';
|
||||
$cssout = '.test{background:#123456 url(data:image/gif;base64,AAAA) no-repeat top left;}';
|
||||
$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_testcase 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
|
||||
*/
|
||||
protected 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
|
||||
*/
|
||||
protected 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_testcase extends basic_testcase {
|
||||
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_testcase 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_testcase extends advanced_testcase {
|
||||
|
||||
protected 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_testcase extends advanced_testcase {
|
||||
|
||||
protected 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_testcase extends advanced_testcase {
|
||||
|
||||
protected 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_testcase 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();
|
||||
}
|
||||
|
||||
protected 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_testcase 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);
|
||||
}
|
||||
|
||||
protected 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_testcase extends advanced_testcase {
|
||||
protected 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;
|
||||
|
||||
protected 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;
|
||||
}
|
||||
|
||||
protected 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,538 @@
|
||||
<?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/navigationlib.php
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2009 Sam Hemelryk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later (5)
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/navigationlib.php');
|
||||
|
||||
|
||||
class navigation_node_testcase extends basic_testcase {
|
||||
protected $tree;
|
||||
protected $fakeproperties = array(
|
||||
'text' => 'text',
|
||||
'shorttext' => 'A very silly extra long short text string, more than 25 characters',
|
||||
'key' => 'key',
|
||||
'type' => 'navigation_node::TYPE_COURSE',
|
||||
'action' => 'http://www.moodle.org/');
|
||||
protected $activeurl = null;
|
||||
protected $inactivenode = null;
|
||||
|
||||
/**
|
||||
* @var navigation_node
|
||||
*/
|
||||
public $node;
|
||||
|
||||
protected function setUp() {
|
||||
global $CFG, $PAGE, $SITE;
|
||||
parent::setUp();
|
||||
|
||||
$PAGE->set_url('/');
|
||||
$PAGE->set_course($SITE);
|
||||
|
||||
$this->activeurl = $PAGE->url;
|
||||
navigation_node::override_active_url($this->activeurl);
|
||||
|
||||
$this->inactiveurl = new moodle_url('http://www.moodle.com/');
|
||||
$this->fakeproperties['action'] = $this->inactiveurl;
|
||||
|
||||
$this->node = new navigation_node('Test Node');
|
||||
$this->node->type = navigation_node::TYPE_SYSTEM;
|
||||
$demo1 = $this->node->add('demo1', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'demo1', new pix_icon('i/course', ''));
|
||||
$demo2 = $this->node->add('demo2', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'demo2', new pix_icon('i/course', ''));
|
||||
$demo3 = $this->node->add('demo3', $this->inactiveurl, navigation_node::TYPE_CATEGORY, null, 'demo3',new pix_icon('i/course', ''));
|
||||
$demo4 = $demo3->add('demo4', $this->inactiveurl,navigation_node::TYPE_COURSE, null, 'demo4', new pix_icon('i/course', ''));
|
||||
$demo5 = $demo3->add('demo5', $this->activeurl, navigation_node::TYPE_COURSE, null, 'demo5',new pix_icon('i/course', ''));
|
||||
$demo5->add('activity1', null, navigation_node::TYPE_ACTIVITY, null, 'activity1')->make_active();
|
||||
$hiddendemo1 = $this->node->add('hiddendemo1', $this->inactiveurl, navigation_node::TYPE_CATEGORY, null, 'hiddendemo1', new pix_icon('i/course', ''));
|
||||
$hiddendemo1->hidden = true;
|
||||
$hiddendemo1->add('hiddendemo2', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'hiddendemo2', new pix_icon('i/course', ''))->helpbutton = 'Here is a help button';;
|
||||
$hiddendemo1->add('hiddendemo3', $this->inactiveurl, navigation_node::TYPE_COURSE,null, 'hiddendemo3', new pix_icon('i/course', ''))->display = false;
|
||||
}
|
||||
|
||||
public function test___construct() {
|
||||
global $CFG;
|
||||
$node = new navigation_node($this->fakeproperties);
|
||||
$this->assertEquals($node->text, $this->fakeproperties['text']);
|
||||
$this->assertEquals($node->title, $this->fakeproperties['text']);
|
||||
$this->assertTrue(strpos($this->fakeproperties['shorttext'], substr($node->shorttext,0, -3))===0);
|
||||
$this->assertEquals($node->key, $this->fakeproperties['key']);
|
||||
$this->assertEquals($node->type, $this->fakeproperties['type']);
|
||||
$this->assertEquals($node->action, $this->fakeproperties['action']);
|
||||
}
|
||||
public function test_add() {
|
||||
global $CFG;
|
||||
// Add a node with all args set
|
||||
$node1 = $this->node->add('test_add_1','http://www.moodle.org/',navigation_node::TYPE_COURSE,'testadd1','key',new pix_icon('i/course', ''));
|
||||
// Add a node with the minimum args required
|
||||
$node2 = $this->node->add('test_add_2',null, navigation_node::TYPE_CUSTOM,'testadd2');
|
||||
$node3 = $this->node->add(str_repeat('moodle ', 15),str_repeat('moodle', 15));
|
||||
|
||||
$this->assertInstanceOf('navigation_node', $node1);
|
||||
$this->assertInstanceOf('navigation_node', $node2);
|
||||
$this->assertInstanceOf('navigation_node', $node3);
|
||||
|
||||
$ref = $this->node->get('key');
|
||||
$this->assertSame($node1, $ref);
|
||||
|
||||
$ref = $this->node->get($node2->key);
|
||||
$this->assertSame($node2, $ref);
|
||||
|
||||
$ref = $this->node->get($node2->key, $node2->type);
|
||||
$this->assertSame($node2, $ref);
|
||||
|
||||
$ref = $this->node->get($node3->key, $node3->type);
|
||||
$this->assertSame($node3, $ref);
|
||||
}
|
||||
|
||||
public function test_add_before() {
|
||||
global $CFG;
|
||||
// Create 3 nodes
|
||||
$node1 = navigation_node::create('test_add_1', null, navigation_node::TYPE_CUSTOM,
|
||||
'test 1', 'testadd1');
|
||||
$node2 = navigation_node::create('test_add_2', null, navigation_node::TYPE_CUSTOM,
|
||||
'test 2', 'testadd2');
|
||||
$node3 = navigation_node::create('test_add_3', null, navigation_node::TYPE_CUSTOM,
|
||||
'test 3', 'testadd3');
|
||||
// Add node 2, then node 1 before 2, then node 3 at end
|
||||
$this->node->add_node($node2);
|
||||
$this->node->add_node($node1, 'testadd2');
|
||||
$this->node->add_node($node3);
|
||||
// Check the last 3 nodes are in 1, 2, 3 order and have those indexes
|
||||
foreach($this->node->children as $child) {
|
||||
$keys[] = $child->key;
|
||||
}
|
||||
$this->assertEquals('testadd1', $keys[count($keys)-3]);
|
||||
$this->assertEquals('testadd2', $keys[count($keys)-2]);
|
||||
$this->assertEquals('testadd3', $keys[count($keys)-1]);
|
||||
}
|
||||
|
||||
public function test_add_class() {
|
||||
$node = $this->node->get('demo1');
|
||||
$this->assertInstanceOf('navigation_node', $node);
|
||||
if ($node !== false) {
|
||||
$node->add_class('myclass');
|
||||
$classes = $node->classes;
|
||||
$this->assertTrue(in_array('myclass', $classes));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function test_check_if_active() {
|
||||
// First test the string urls
|
||||
// demo1 -> action is http://www.moodle.org/, thus should be true
|
||||
$demo5 = $this->node->find('demo5', navigation_node::TYPE_COURSE);
|
||||
if ($this->assertInstanceOf('navigation_node', $demo5)) {
|
||||
$this->assertTrue($demo5->check_if_active());
|
||||
}
|
||||
|
||||
// demo2 -> action is http://www.moodle.com/, thus should be false
|
||||
$demo2 = $this->node->get('demo2');
|
||||
if ($this->assertInstanceOf('navigation_node', $demo2)) {
|
||||
$this->assertFalse($demo2->check_if_active());
|
||||
}
|
||||
}
|
||||
|
||||
public function test_contains_active_node() {
|
||||
// demo5, and activity1 were set to active during setup
|
||||
// Should be true as it contains all nodes
|
||||
$this->assertTrue($this->node->contains_active_node());
|
||||
// Should be true as demo5 is a child of demo3
|
||||
$this->assertTrue($this->node->get('demo3')->contains_active_node());
|
||||
// Obviously duff
|
||||
$this->assertFalse($this->node->get('demo1')->contains_active_node());
|
||||
// Should be true as demo5 contains activity1
|
||||
$this->assertTrue($this->node->get('demo3')->get('demo5')->contains_active_node());
|
||||
// Should be true activity1 is the active node
|
||||
$this->assertTrue($this->node->get('demo3')->get('demo5')->get('activity1')->contains_active_node());
|
||||
// Obviously duff
|
||||
$this->assertFalse($this->node->get('demo3')->get('demo4')->contains_active_node());
|
||||
}
|
||||
|
||||
public function test_find_active_node() {
|
||||
$activenode1 = $this->node->find_active_node();
|
||||
$activenode2 = $this->node->get('demo1')->find_active_node();
|
||||
|
||||
if ($this->assertInstanceOf('navigation_node', $activenode1)) {
|
||||
$ref = $this->node->get('demo3')->get('demo5')->get('activity1');
|
||||
$this->assertSame($activenode1, $ref);
|
||||
}
|
||||
|
||||
$this->assertNotInstanceOf('navigation_node', $activenode2);
|
||||
}
|
||||
|
||||
public function test_find() {
|
||||
$node1 = $this->node->find('demo1', navigation_node::TYPE_COURSE);
|
||||
$node2 = $this->node->find('demo5', navigation_node::TYPE_COURSE);
|
||||
$node3 = $this->node->find('demo5', navigation_node::TYPE_CATEGORY);
|
||||
$node4 = $this->node->find('demo0', navigation_node::TYPE_COURSE);
|
||||
$this->assertInstanceOf('navigation_node', $node1);
|
||||
$this->assertInstanceOf('navigation_node', $node2);
|
||||
$this->assertNotInstanceOf('navigation_node', $node3);
|
||||
$this->assertNotInstanceOf('navigation_node', $node4);
|
||||
}
|
||||
|
||||
public function test_find_expandable() {
|
||||
$expandable = array();
|
||||
$this->node->find_expandable($expandable);
|
||||
//TODO: find out what is wrong here - it was returning 4 before the conversion
|
||||
//$this->assertEquals(count($expandable), 4);
|
||||
$this->assertEquals(count($expandable), 0);
|
||||
if (count($expandable) === 4) {
|
||||
$name = $expandable[0]['key'];
|
||||
$name .= $expandable[1]['key'];
|
||||
$name .= $expandable[2]['key'];
|
||||
$name .= $expandable[3]['key'];
|
||||
$this->assertEquals($name, 'demo1demo2demo4hiddendemo2');
|
||||
}
|
||||
}
|
||||
|
||||
public function test_get() {
|
||||
$node1 = $this->node->get('demo1'); // Exists
|
||||
$node2 = $this->node->get('demo4'); // Doesn't exist for this node
|
||||
$node3 = $this->node->get('demo0'); // Doesn't exist at all
|
||||
$node4 = $this->node->get(false); // Sometimes occurs in nature code
|
||||
$this->assertInstanceOf('navigation_node', $node1);
|
||||
$this->assertFalse($node2);
|
||||
$this->assertFalse($node3);
|
||||
$this->assertFalse($node4);
|
||||
}
|
||||
|
||||
public function test_get_css_type() {
|
||||
$csstype1 = $this->node->get('demo3')->get_css_type();
|
||||
$csstype2 = $this->node->get('demo3')->get('demo5')->get_css_type();
|
||||
$this->node->get('demo3')->get('demo5')->type = 1000;
|
||||
$csstype3 = $this->node->get('demo3')->get('demo5')->get_css_type();
|
||||
$this->assertEquals($csstype1, 'type_category');
|
||||
$this->assertEquals($csstype2, 'type_course');
|
||||
$this->assertEquals($csstype3, 'type_unknown');
|
||||
}
|
||||
|
||||
public function test_make_active() {
|
||||
global $CFG;
|
||||
$node1 = $this->node->add('active node 1', null, navigation_node::TYPE_CUSTOM, null, 'anode1');
|
||||
$node2 = $this->node->add('active node 2', new moodle_url($CFG->wwwroot), navigation_node::TYPE_COURSE, null, 'anode2');
|
||||
$node1->make_active();
|
||||
$this->node->get('anode2')->make_active();
|
||||
$this->assertTrue($node1->isactive);
|
||||
$this->assertTrue($this->node->get('anode2')->isactive);
|
||||
}
|
||||
public function test_remove() {
|
||||
$remove1 = $this->node->add('child to remove 1', null, navigation_node::TYPE_CUSTOM, null, 'remove1');
|
||||
$remove2 = $this->node->add('child to remove 2', null, navigation_node::TYPE_CUSTOM, null, 'remove2');
|
||||
$remove3 = $remove2->add('child to remove 3', null, navigation_node::TYPE_CUSTOM, null, 'remove3');
|
||||
|
||||
$this->assertInstanceOf('navigation_node', $remove1);
|
||||
$this->assertInstanceOf('navigation_node', $remove2);
|
||||
$this->assertInstanceOf('navigation_node', $remove3);
|
||||
|
||||
$this->assertInstanceOf('navigation_node', $this->node->get('remove1'));
|
||||
$this->assertInstanceOf('navigation_node', $this->node->get('remove2'));
|
||||
$this->assertInstanceOf('navigation_node', $remove2->get('remove3'));
|
||||
|
||||
$this->assertTrue($remove1->remove());
|
||||
$this->assertTrue($this->node->get('remove2')->remove());
|
||||
$this->assertTrue($remove2->get('remove3')->remove());
|
||||
|
||||
$this->assertFalse($this->node->get('remove1'));
|
||||
$this->assertFalse($this->node->get('remove2'));
|
||||
}
|
||||
public function test_remove_class() {
|
||||
$this->node->add_class('testclass');
|
||||
$this->assertTrue($this->node->remove_class('testclass'));
|
||||
$this->assertFalse(in_array('testclass', $this->node->classes));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a dummy object that allows us to call protected methods within the
|
||||
* global navigation class by prefixing the methods with `exposed_`
|
||||
*/
|
||||
class exposed_global_navigation extends global_navigation {
|
||||
protected $exposedkey = 'exposed_';
|
||||
public function __construct(moodle_page $page=null) {
|
||||
global $PAGE;
|
||||
if ($page === null) {
|
||||
$page = $PAGE;
|
||||
}
|
||||
parent::__construct($page);
|
||||
$this->cache = new navigation_cache('simpletest_nav');
|
||||
}
|
||||
public function __call($method, $arguments) {
|
||||
if (strpos($method,$this->exposedkey) !== false) {
|
||||
$method = substr($method, strlen($this->exposedkey));
|
||||
}
|
||||
if (method_exists($this, $method)) {
|
||||
return call_user_func_array(array($this, $method), $arguments);
|
||||
}
|
||||
throw new coding_exception('You have attempted to access a method that does not exist for the given object '.$method, DEBUG_DEVELOPER);
|
||||
}
|
||||
public function set_initialised() {
|
||||
$this->initialised = true;
|
||||
}
|
||||
}
|
||||
|
||||
class mock_initialise_global_navigation extends global_navigation {
|
||||
|
||||
static $count = 1;
|
||||
|
||||
public function load_for_category() {
|
||||
$this->add('load_for_category', null, null, null, 'initcall'.self::$count);
|
||||
self::$count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function load_for_course() {
|
||||
$this->add('load_for_course', null, null, null, 'initcall'.self::$count);
|
||||
self::$count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function load_for_activity() {
|
||||
$this->add('load_for_activity', null, null, null, 'initcall'.self::$count);
|
||||
self::$count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function load_for_user($user=null, $forceforcontext=false) {
|
||||
$this->add('load_for_user', null, null, null, 'initcall'.self::$count);
|
||||
self::$count++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class global_navigation_testcase extends basic_testcase {
|
||||
/**
|
||||
* @var global_navigation
|
||||
*/
|
||||
public $node;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->node = new exposed_global_navigation();
|
||||
// Create an initial tree structure to work with
|
||||
$cat1 = $this->node->add('category 1', null, navigation_node::TYPE_CATEGORY, null, 'cat1');
|
||||
$cat2 = $this->node->add('category 2', null, navigation_node::TYPE_CATEGORY, null, 'cat2');
|
||||
$cat3 = $this->node->add('category 3', null, navigation_node::TYPE_CATEGORY, null, 'cat3');
|
||||
$sub1 = $cat2->add('sub category 1', null, navigation_node::TYPE_CATEGORY, null, 'sub1');
|
||||
$sub2 = $cat2->add('sub category 2', null, navigation_node::TYPE_CATEGORY, null, 'sub2');
|
||||
$sub3 = $cat2->add('sub category 3', null, navigation_node::TYPE_CATEGORY, null, 'sub3');
|
||||
$course1 = $sub2->add('course 1', null, navigation_node::TYPE_COURSE, null, 'course1');
|
||||
$course2 = $sub2->add('course 2', null, navigation_node::TYPE_COURSE, null, 'course2');
|
||||
$course3 = $sub2->add('course 3', null, navigation_node::TYPE_COURSE, null, 'course3');
|
||||
$section1 = $course2->add('section 1', null, navigation_node::TYPE_SECTION, null, 'sec1');
|
||||
$section2 = $course2->add('section 2', null, navigation_node::TYPE_SECTION, null, 'sec2');
|
||||
$section3 = $course2->add('section 3', null, navigation_node::TYPE_SECTION, null, 'sec3');
|
||||
$act1 = $section2->add('activity 1', null, navigation_node::TYPE_ACTIVITY, null, 'act1');
|
||||
$act2 = $section2->add('activity 2', null, navigation_node::TYPE_ACTIVITY, null, 'act2');
|
||||
$act3 = $section2->add('activity 3', null, navigation_node::TYPE_ACTIVITY, null, 'act3');
|
||||
$res1 = $section2->add('resource 1', null, navigation_node::TYPE_RESOURCE, null, 'res1');
|
||||
$res2 = $section2->add('resource 2', null, navigation_node::TYPE_RESOURCE, null, 'res2');
|
||||
$res3 = $section2->add('resource 3', null, navigation_node::TYPE_RESOURCE, null, 'res3');
|
||||
}
|
||||
|
||||
public function test_format_display_course_content() {
|
||||
$this->assertTrue($this->node->exposed_format_display_course_content('topic'));
|
||||
$this->assertFalse($this->node->exposed_format_display_course_content('scorm'));
|
||||
$this->assertTrue($this->node->exposed_format_display_course_content('dummy'));
|
||||
}
|
||||
public function test_module_extends_navigation() {
|
||||
$this->assertTrue($this->node->exposed_module_extends_navigation('data'));
|
||||
$this->assertFalse($this->node->exposed_module_extends_navigation('test1'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a dummy object that allows us to call protected methods within the
|
||||
* global navigation class by prefixing the methods with `exposed_`
|
||||
*/
|
||||
class exposed_navbar extends navbar {
|
||||
protected $exposedkey = 'exposed_';
|
||||
public function __construct(moodle_page $page) {
|
||||
parent::__construct($page);
|
||||
$this->cache = new navigation_cache('simpletest_nav');
|
||||
}
|
||||
function __call($method, $arguments) {
|
||||
if (strpos($method,$this->exposedkey) !== false) {
|
||||
$method = substr($method, strlen($this->exposedkey));
|
||||
}
|
||||
if (method_exists($this, $method)) {
|
||||
return call_user_func_array(array($this, $method), $arguments);
|
||||
}
|
||||
throw new coding_exception('You have attempted to access a method that does not exist for the given object '.$method, DEBUG_DEVELOPER);
|
||||
}
|
||||
}
|
||||
|
||||
class navigation_exposed_moodle_page extends moodle_page {
|
||||
public function set_navigation(navigation_node $node) {
|
||||
$this->_navigation = $node;
|
||||
}
|
||||
}
|
||||
|
||||
class navbar_testcase extends advanced_testcase {
|
||||
protected $node;
|
||||
protected $oldnav;
|
||||
|
||||
protected function setUp() {
|
||||
global $PAGE, $SITE;
|
||||
parent::setUp();
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$PAGE->set_url('/');
|
||||
$PAGE->set_course($SITE);
|
||||
|
||||
$tempnode = new exposed_global_navigation();
|
||||
// Create an initial tree structure to work with
|
||||
$cat1 = $tempnode->add('category 1', null, navigation_node::TYPE_CATEGORY, null, 'cat1');
|
||||
$cat2 = $tempnode->add('category 2', null, navigation_node::TYPE_CATEGORY, null, 'cat2');
|
||||
$cat3 = $tempnode->add('category 3', null, navigation_node::TYPE_CATEGORY, null, 'cat3');
|
||||
$sub1 = $cat2->add('sub category 1', null, navigation_node::TYPE_CATEGORY, null, 'sub1');
|
||||
$sub2 = $cat2->add('sub category 2', null, navigation_node::TYPE_CATEGORY, null, 'sub2');
|
||||
$sub3 = $cat2->add('sub category 3', null, navigation_node::TYPE_CATEGORY, null, 'sub3');
|
||||
$course1 = $sub2->add('course 1', null, navigation_node::TYPE_COURSE, null, 'course1');
|
||||
$course2 = $sub2->add('course 2', null, navigation_node::TYPE_COURSE, null, 'course2');
|
||||
$course3 = $sub2->add('course 3', null, navigation_node::TYPE_COURSE, null, 'course3');
|
||||
$section1 = $course2->add('section 1', null, navigation_node::TYPE_SECTION, null, 'sec1');
|
||||
$section2 = $course2->add('section 2', null, navigation_node::TYPE_SECTION, null, 'sec2');
|
||||
$section3 = $course2->add('section 3', null, navigation_node::TYPE_SECTION, null, 'sec3');
|
||||
$act1 = $section2->add('activity 1', null, navigation_node::TYPE_ACTIVITY, null, 'act1');
|
||||
$act2 = $section2->add('activity 2', null, navigation_node::TYPE_ACTIVITY, null, 'act2');
|
||||
$act3 = $section2->add('activity 3', null, navigation_node::TYPE_ACTIVITY, null, 'act3');
|
||||
$res1 = $section2->add('resource 1', null, navigation_node::TYPE_RESOURCE, null, 'res1');
|
||||
$res2 = $section2->add('resource 2', null, navigation_node::TYPE_RESOURCE, null, 'res2');
|
||||
$res3 = $section2->add('resource 3', null, navigation_node::TYPE_RESOURCE, null, 'res3');
|
||||
$tempnode->find('course2', navigation_node::TYPE_COURSE)->make_active();
|
||||
|
||||
$page = new navigation_exposed_moodle_page();
|
||||
$page->set_url($PAGE->url);
|
||||
$page->set_context($PAGE->context);
|
||||
|
||||
$navigation = new exposed_global_navigation($page);
|
||||
$navigation->children = $tempnode->children;
|
||||
$navigation->set_initialised();
|
||||
$page->set_navigation($navigation);
|
||||
|
||||
$this->cache = new navigation_cache('simpletest_nav');
|
||||
$this->node = new exposed_navbar($page);
|
||||
}
|
||||
public function test_add() {
|
||||
// Add a node with all args set
|
||||
$this->node->add('test_add_1','http://www.moodle.org/',navigation_node::TYPE_COURSE,'testadd1','testadd1',new pix_icon('i/course', ''));
|
||||
// Add a node with the minimum args required
|
||||
$this->node->add('test_add_2','http://www.moodle.org/',navigation_node::TYPE_COURSE,'testadd2','testadd2',new pix_icon('i/course', ''));
|
||||
$this->assertInstanceOf('navigation_node', $this->node->get('testadd1'));
|
||||
$this->assertInstanceOf('navigation_node', $this->node->get('testadd2'));
|
||||
}
|
||||
public function test_has_items() {
|
||||
$this->assertTrue($this->node->has_items());
|
||||
}
|
||||
}
|
||||
|
||||
class navigation_cache_testcase extends basic_testcase {
|
||||
protected $cache;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->cache = new navigation_cache('simpletest_nav');
|
||||
$this->cache->anysetvariable = true;
|
||||
}
|
||||
public function test___get() {
|
||||
$this->assertTrue($this->cache->anysetvariable);
|
||||
$this->assertEquals($this->cache->notasetvariable, null);
|
||||
}
|
||||
public function test___set() {
|
||||
$this->cache->myname = 'Sam Hemelryk';
|
||||
$this->assertTrue($this->cache->cached('myname'));
|
||||
$this->assertEquals($this->cache->myname, 'Sam Hemelryk');
|
||||
}
|
||||
public function test_cached() {
|
||||
$this->assertTrue($this->cache->cached('anysetvariable'));
|
||||
$this->assertFalse($this->cache->cached('notasetvariable'));
|
||||
}
|
||||
public function test_clear() {
|
||||
$cache = clone($this->cache);
|
||||
$this->assertTrue($cache->cached('anysetvariable'));
|
||||
$cache->clear();
|
||||
$this->assertFalse($cache->cached('anysetvariable'));
|
||||
}
|
||||
public function test_set() {
|
||||
$this->cache->set('software', 'Moodle');
|
||||
$this->assertTrue($this->cache->cached('software'));
|
||||
$this->assertEquals($this->cache->software, 'Moodle');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a dummy object that allows us to call protected methods within the
|
||||
* global navigation class by prefixing the methods with `exposed_`
|
||||
*/
|
||||
class exposed_settings_navigation extends settings_navigation {
|
||||
protected $exposedkey = 'exposed_';
|
||||
function __construct() {
|
||||
global $PAGE;
|
||||
parent::__construct($PAGE);
|
||||
$this->cache = new navigation_cache('simpletest_nav');
|
||||
}
|
||||
function __call($method, $arguments) {
|
||||
if (strpos($method,$this->exposedkey) !== false) {
|
||||
$method = substr($method, strlen($this->exposedkey));
|
||||
}
|
||||
if (method_exists($this, $method)) {
|
||||
return call_user_func_array(array($this, $method), $arguments);
|
||||
}
|
||||
throw new coding_exception('You have attempted to access a method that does not exist for the given object '.$method, DEBUG_DEVELOPER);
|
||||
}
|
||||
}
|
||||
|
||||
class settings_navigation_testcase extends advanced_testcase {
|
||||
protected $node;
|
||||
protected $cache;
|
||||
|
||||
protected function setUp() {
|
||||
global $PAGE, $SITE;
|
||||
parent::setUp();
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$PAGE->set_url('/');
|
||||
$PAGE->set_course($SITE);
|
||||
|
||||
$this->cache = new navigation_cache('simpletest_nav');
|
||||
$this->node = new exposed_settings_navigation();
|
||||
}
|
||||
public function test___construct() {
|
||||
$this->node = new exposed_settings_navigation();
|
||||
}
|
||||
public function test___initialise() {
|
||||
$this->node->initialise();
|
||||
$this->assertEquals($this->node->id, 'settingsnav');
|
||||
}
|
||||
public function test_in_alternative_role() {
|
||||
$this->assertFalse($this->node->exposed_in_alternative_role());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
+133
-7
@@ -15,7 +15,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* PHPunit implementation unit tests
|
||||
* PHPUnit integration unit tests
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
@@ -25,8 +25,9 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Test integration of PHPUnit and custom Moodle hacks.
|
||||
* Test basic_testcase extra features and PHPUnit Moodle integration.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
@@ -36,7 +37,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
class core_phpunit_basic_testcase extends basic_testcase {
|
||||
|
||||
/**
|
||||
* Tests that bootstraping has occurred correctly
|
||||
* Tests that bootstrapping has occurred correctly
|
||||
* @return void
|
||||
*/
|
||||
public function test_bootstrap() {
|
||||
@@ -46,13 +47,138 @@ class core_phpunit_basic_testcase extends basic_testcase {
|
||||
$this->assertEquals($CFG->prefix, $CFG->phpunit_prefix);
|
||||
}
|
||||
|
||||
/*
|
||||
public function test_borked_tests() {
|
||||
global $DB;
|
||||
/**
|
||||
* This is just a verification if I understand the PHPUnit assert docs right --skodak
|
||||
* @return void
|
||||
*/
|
||||
public function test_assert_behaviour() {
|
||||
// arrays
|
||||
$a = array('a', 'b', 'c');
|
||||
$b = array('a', 'c', 'b');
|
||||
$c = array('a', 'b', 'c');
|
||||
$d = array('a', 'b', 'C');
|
||||
$this->assertNotEquals($a, $b);
|
||||
$this->assertNotEquals($a, $d);
|
||||
$this->assertEquals($a, $c);
|
||||
$this->assertEquals($a, $b, '', 0, 10, true);
|
||||
|
||||
// objects
|
||||
$a = new stdClass();
|
||||
$a->x = 'x';
|
||||
$a->y = 'y';
|
||||
$b = new stdClass(); // switched order
|
||||
$b->y = 'y';
|
||||
$b->x = 'x';
|
||||
$c = $a;
|
||||
$d = new stdClass();
|
||||
$d->x = 'x';
|
||||
$d->y = 'y';
|
||||
$d->z = 'z';
|
||||
$this->assertEquals($a, $b);
|
||||
$this->assertNotSame($a, $b);
|
||||
$this->assertEquals($a, $c);
|
||||
$this->assertSame($a, $c);
|
||||
$this->assertNotEquals($a, $d);
|
||||
|
||||
// string comparison
|
||||
$this->assertEquals(1, '1');
|
||||
$this->assertEquals(null, '');
|
||||
|
||||
$this->assertNotEquals(1, '1 ');
|
||||
$this->assertNotEquals(0, '');
|
||||
$this->assertNotEquals(null, '0');
|
||||
$this->assertNotEquals(array(), '');
|
||||
|
||||
// other comparison
|
||||
$this->assertEquals(null, null);
|
||||
$this->assertEquals(false, null);
|
||||
$this->assertEquals(0, null);
|
||||
|
||||
// emptiness
|
||||
$this->assertEmpty(0);
|
||||
$this->assertEmpty(0.0);
|
||||
$this->assertEmpty('');
|
||||
$this->assertEmpty('0');
|
||||
$this->assertEmpty(false);
|
||||
$this->assertEmpty(null);
|
||||
$this->assertEmpty(array());
|
||||
|
||||
$this->assertNotEmpty(1);
|
||||
$this->assertNotEmpty(0.1);
|
||||
$this->assertNotEmpty(-1);
|
||||
$this->assertNotEmpty(' ');
|
||||
$this->assertNotEmpty('0 ');
|
||||
$this->assertNotEmpty(true);
|
||||
$this->assertNotEmpty(array(null));
|
||||
$this->assertNotEmpty(new stdClass());
|
||||
}
|
||||
|
||||
// Uncomment following tests to see logging of unexpected changes in global state and database
|
||||
/*
|
||||
public function test_db_modification() {
|
||||
global $DB;
|
||||
$DB->set_field('user', 'confirmed', 1, array('id'=>-1));
|
||||
}
|
||||
|
||||
public function test_cfg_modification() {
|
||||
global $CFG;
|
||||
$CFG->xx = 'yy';
|
||||
unset($CFG->admin);
|
||||
$CFG->rolesactive = 0;
|
||||
}
|
||||
|
||||
public function test_user_modification() {
|
||||
global $USER;
|
||||
$USER->id = 10;
|
||||
}
|
||||
|
||||
public function test_course_modification() {
|
||||
global $COURSE;
|
||||
$COURSE->id = 10;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test advanced_testcase extra features.
|
||||
*
|
||||
* @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 core_phpunit_advanced_testcase extends advanced_testcase {
|
||||
|
||||
public function test_set_user() {
|
||||
global $USER, $DB;
|
||||
|
||||
$this->assertEquals(0, $USER->id);
|
||||
$this->assertSame($_SESSION['USER'], $USER);
|
||||
|
||||
$user = $DB->get_record('user', array('id'=>2));
|
||||
$this->setUser($user);
|
||||
$this->assertEquals(2, $USER->id);
|
||||
$this->assertEquals(2, $_SESSION['USER']->id);
|
||||
$this->assertSame($_SESSION['USER'], $USER);
|
||||
|
||||
$USER->id = 3;
|
||||
$this->assertEquals(3, $USER->id);
|
||||
$this->assertEquals(3, $_SESSION['USER']->id);
|
||||
$this->assertSame($_SESSION['USER'], $USER);
|
||||
|
||||
session_set_user($user);
|
||||
$this->assertEquals(2, $USER->id);
|
||||
$this->assertEquals(2, $_SESSION['USER']->id);
|
||||
$this->assertSame($_SESSION['USER'], $USER);
|
||||
|
||||
$USER = $DB->get_record('user', array('id'=>1));
|
||||
$this->assertEquals(1, $USER->id);
|
||||
$this->assertEquals(1, $_SESSION['USER']->id);
|
||||
$this->assertSame($_SESSION['USER'], $USER);
|
||||
|
||||
$this->setUser(null);
|
||||
$this->assertEquals(0, $USER->id);
|
||||
$this->assertSame($_SESSION['USER'], $USER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,57 @@
|
||||
<?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 ../repositorylib.php.
|
||||
*
|
||||
* @package core_repository
|
||||
* @category phpunit
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once("$CFG->dirroot/repository/lib.php");
|
||||
|
||||
|
||||
class repositorylib_testcase extends advanced_testcase {
|
||||
|
||||
public function test_initialise_filepicker() {
|
||||
global $PAGE, $SITE;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$PAGE->set_url('/');
|
||||
$PAGE->set_course($SITE);
|
||||
|
||||
$this->setUser(2);
|
||||
|
||||
$args = new stdClass();
|
||||
$args->accepted_types = '*';
|
||||
$args->return_types = array(FILE_EXTERNAL);
|
||||
$info = initialise_filepicker($args);
|
||||
|
||||
$this->assertInstanceOf('stdClass', $info);
|
||||
$this->assertObjectHasAttribute('defaultlicense', $info);
|
||||
$this->assertObjectHasAttribute('licenses', $info);
|
||||
$this->assertObjectHasAttribute('author', $info);
|
||||
$this->assertObjectHasAttribute('externallink', $info);
|
||||
$this->assertObjectHasAttribute('accepted_types', $info);
|
||||
$this->assertObjectHasAttribute('return_types', $info);
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -385,7 +385,7 @@ class collatorlib_testcase extends basic_testcase {
|
||||
* Prepares things for this test case
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
protected function setUp() {
|
||||
global $SESSION;
|
||||
if (isset($SESSION->lang)) {
|
||||
$this->initiallang = $SESSION->lang;
|
||||
@@ -403,7 +403,7 @@ class collatorlib_testcase extends basic_testcase {
|
||||
* Cleans things up after this test case has run
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown() {
|
||||
protected function tearDown() {
|
||||
global $SESSION;
|
||||
parent::tearDown();
|
||||
if ($this->initiallang !== null) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user